medmis-core-orchestrator / testrunner.html
muboboev's picture
к каждому интерфейсу и стратице добаль кномку назад для перехода на преведующу страницу
f8ad23e verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test Runner | MedMIS</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
}
.test-card {
transition: all 0.2s ease;
}
.test-card:hover {
transform: translateY(-2px);
}
.status-running {
background-color: #f59e0b20;
color: #f59e0b;
}
.status-passed {
background-color: #10b98120;
color: #10b981;
}
.status-failed {
background-color: #ef444420;
color: #ef4444;
}
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<div class="container mx-auto px-4 py-8">
<header class="mb-8">
<div class="flex items-center mb-4">
<button onclick="history.back()" class="mr-4 p-2 rounded-lg bg-gray-700 hover:bg-gray-600 transition">
<i data-feather="arrow-left" class="w-5 h-5"></i>
</button>
<div>
<h1 class="text-3xl font-bold">Test Runner</h1>
<p class="text-gray-300">Automated testing for MedMIS workflows</p>
</div>
</div>
</header>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
<!-- Test Scenarios -->
<div class="lg:col-span-2 bg-gray-800 rounded-xl p-6">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<i data-feather="list" class="w-5 h-5 mr-2"></i>
Test Scenarios
</h2>
<div class="space-y-3" id="testScenarios">
<div class="test-card bg-gray-700 rounded-lg p-4 cursor-pointer hover:bg-gray-600">
<div class="flex justify-between items-start">
<div>
<h3 class="font-medium">Patient Flow</h3>
<p class="text-sm text-gray-400">Registration → Queue → Study → Report</p>
</div>
<button class="run-test bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm" data-test="patientFlow">
Run
</button>
</div>
</div>
<div class="test-card bg-gray-700 rounded-lg p-4 cursor-pointer hover:bg-gray-600">
<div class="flex justify-between items-start">
<div>
<h3 class="font-medium">SLA Compliance</h3>
<p class="text-sm text-gray-400">Priority-based timing and scoring</p>
</div>
<button class="run-test bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm" data-test="slaCompliance">
Run
</button>
</div>
</div>
<div class="test-card bg-gray-700 rounded-lg p-4 cursor-pointer hover:bg-gray-600">
<div class="flex justify-between items-start">
<div>
<h3 class="font-medium">Integration Flow</h3>
<p class="text-sm text-gray-400">Service-to-service event routing</p>
</div>
<button class="run-test bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm" data-test="integrationFlow">
Run
</button>
</div>
</div>
</div>
</div>
<!-- Test Results -->
<div class="bg-gray-800 rounded-xl p-6">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<i data-feather="check-circle" class="w-5 h-5 mr-2"></i>
Test Results
</h2>
<div id="testResults" class="space-y-3">
<div class="bg-gray-700 rounded-lg p-4">
<div class="flex justify-between mb-2">
<span class="font-medium">Last Run:</span>
<span class="text-gray-400">Not run yet</span>
</div>
<div class="flex justify-between">
<span class="font-medium">Status:</span>
<span class="text-gray-400">Idle</span>
</div>
</div>
<div id="testLogs" class="bg-gray-900 rounded-lg p-4 h-64 overflow-y-auto text-sm font-mono">
<!-- Test logs will appear here -->
</div>
</div>
</div>
</div>
<!-- API Test Console -->
<div class="bg-gray-800 rounded-xl p-6 mb-8">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<i data-feather="terminal" class="w-5 h-5 mr-2"></i>
API Test Console
</h2>
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-4">
<div>
<label class="block text-gray-300 text-sm mb-1">Method</label>
<select id="apiMethod" class="w-full bg-gray-700 rounded-lg px-3 py-2">
<option>GET</option>
<option>POST</option>
<option>PUT</option>
<option>DELETE</option>
</select>
</div>
<div class="md:col-span-3">
<label class="block text-gray-300 text-sm mb-1">Endpoint</label>
<div class="flex">
<span class="bg-gray-700 rounded-l-lg px-3 py-2">/api/</span>
<input type="text" id="apiEndpoint" class="flex-1 bg-gray-700 rounded-r-lg px-3 py-2" placeholder="endpoint">
</div>
</div>
</div>
<div class="mb-4">
<label class="block text-gray-300 text-sm mb-1">Request Body</label>
<textarea id="apiBody" class="w-full bg-gray-700 rounded-lg px-3 py-2 h-32 font-mono text-sm" placeholder="JSON body"></textarea>
</div>
<button id="runApiTest" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg transition">
Execute API Test
</button>
<div id="apiResponse" class="mt-4 bg-gray-900 rounded-lg p-4 h-64 overflow-y-auto text-sm font-mono hidden">
<div class="text-gray-400">Response will appear here...</div>
</div>
</div>
<!-- Database Configuration -->
<div class="bg-gray-800 rounded-xl p-6">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<i data-feather="database" class="w-5 h-5 mr-2"></i>
Database Configuration
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h3 class="font-medium mb-2">Test Database</h3>
<div class="bg-gray-700 rounded-lg p-4">
<div class="flex items-center justify-between mb-2">
<span>Current:</span>
<span class="font-mono bg-gray-800 px-2 py-1 rounded">SQLite</span>
</div>
<button id="switchDb" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-2 px-4 rounded-lg transition mt-2">
Switch to PostgreSQL
</button>
</div>
</div>
<div>
<h3 class="font-medium mb-2">Sample Data</h3>
<div class="space-y-2">
<button class="w-full bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded-lg transition text-left flex items-center">
<i data-feather="user" class="w-4 h-4 mr-2"></i>
Load Test Patients
</button>
<button class="w-full bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded-lg transition text-left flex items-center">
<i data-feather="book" class="w-4 h-4 mr-2"></i>
Load Test Studies
</button>
<button class="w-full bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded-lg transition text-left flex items-center">
<i data-feather="file-text" class="w-4 h-4 mr-2"></i>
Load Test Reports
</button>
</div>
</div>
</div>
</div>
</div>
<script>
feather.replace();
// Test scenario runner
document.querySelectorAll('.run-test').forEach(button => {
button.addEventListener('click', function() {
const testName = this.dataset.test;
const testLogs = document.getElementById('testLogs');
testLogs.innerHTML = '';
// Update status
const testResults = document.getElementById('testResults');
testResults.querySelector('.bg-gray-700 div:last-child span').textContent = 'Running';
testResults.querySelector('.bg-gray-700 div:last-child span').className = 'text-yellow-400';
logMessage(`Starting ${testName} test...`);
// Simulate test execution
setTimeout(() => {
switch(testName) {
case 'patientFlow':
simulatePatientFlowTest();
break;
case 'slaCompliance':
simulateSlaTest();
break;
case 'integrationFlow':
simulateIntegrationTest();
break;
}
}, 500);
});
});
function logMessage(message) {
const testLogs = document.getElementById('testLogs');
const line = document.createElement('div');
line.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
testLogs.appendChild(line);
testLogs.scrollTop = testLogs.scrollHeight;
}
function simulatePatientFlowTest() {
logMessage("1. Creating test patient...");
setTimeout(() => {
logMessage("✓ Patient created (ID: PT-123456)");
logMessage("2. Adding to queue...");
setTimeout(() => {
logMessage("✓ Added to queue (Q-789012)");
logMessage("3. Starting study...");
setTimeout(() => {
logMessage("✓ Study created (ST-345678)");
logMessage("4. Generating report...");
setTimeout(() => {
logMessage("✓ Report finalized (RP-901234)");
logMessage("5. Checking scores...");
setTimeout(() => {
logMessage("✓ Scores updated (+20 radiologist, +100 referrer)");
// Update status
const testResults = document.getElementById('testResults');
testResults.querySelector('.bg-gray-700 div:first-child span').textContent = new Date().toLocaleString();
testResults.querySelector('.bg-gray-700 div:last-child span').textContent = 'Passed';
testResults.querySelector('.bg-gray-700 div:last-child span').className = 'text-green-400';
logMessage("✅ Test completed successfully");
}, 800);
}, 800);
}, 800);
}, 800);
}, 800);
}
// API test console
document.getElementById('runApiTest').addEventListener('click', function() {
const method = document.getElementById('apiMethod').value;
const endpoint = document.getElementById('apiEndpoint').value;
const body = document.getElementById('apiBody').value;
const responseDiv = document.getElementById('apiResponse');
responseDiv.classList.remove('hidden');
responseDiv.innerHTML = '<div class="text-gray-400">Testing endpoint...</div>';
// Simulate API call
setTimeout(() => {
let response;
try {
const parsedBody = body ? JSON.parse(body) : {};
response = {
status: 200,
data: {
method,
endpoint,
body: parsedBody,
timestamp: new Date().toISOString(),
traceId: 't-' + Math.random().toString(36).substr(2, 8)
}
};
responseDiv.innerHTML = `<div class="text-green-400 mb-2">Request successful (200)</div>
<pre>${JSON.stringify(response, null, 2)}</pre>`;
} catch (e) {
responseDiv.innerHTML = `<div class="text-red-400 mb-2">Error: ${e.message}</div>`;
}
}, 1000);
});
// Database switcher
document.getElementById('switchDb').addEventListener('click', function() {
const button = this;
const currentDb = button.textContent.includes('PostgreSQL') ? 'PostgreSQL' : 'SQLite';
const newDb = currentDb === 'SQLite' ? 'PostgreSQL' : 'SQLite';
logMessage(`Switching database from ${currentDb} to ${newDb}...`);
setTimeout(() => {
button.textContent = `Switch to ${currentDb}`;
button.parentElement.querySelector('span.font-mono').textContent = newDb;
logMessage(`✓ Database switched to ${newDb}`);
}, 1500);
});
</script>
</body>
</html>