Rohanbagulwar commited on
Commit
f5f1dd0
·
1 Parent(s): 7a0e689

static added

Browse files
Files changed (1) hide show
  1. static/index.html +538 -0
static/index.html ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Aeronix Test Case Generator</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
+ min-height: 100vh;
18
+ padding: 20px;
19
+ }
20
+
21
+ .container {
22
+ max-width: 1200px;
23
+ margin: 0 auto;
24
+ }
25
+
26
+ .header {
27
+ text-align: center;
28
+ margin-bottom: 40px;
29
+ color: white;
30
+ }
31
+
32
+ .header h1 {
33
+ font-size: 3rem;
34
+ font-weight: 700;
35
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
36
+ margin-bottom: 10px;
37
+ }
38
+
39
+ .header p {
40
+ font-size: 1.2rem;
41
+ opacity: 0.9;
42
+ }
43
+
44
+ .main-card {
45
+ background: white;
46
+ border-radius: 20px;
47
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
48
+ overflow: hidden;
49
+ backdrop-filter: blur(10px);
50
+ }
51
+
52
+ .form-section {
53
+ padding: 40px;
54
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
55
+ }
56
+
57
+ .form-title {
58
+ font-size: 1.5rem;
59
+ color: #333;
60
+ margin-bottom: 30px;
61
+ text-align: center;
62
+ font-weight: 600;
63
+ }
64
+
65
+ .file-upload-container {
66
+ display: grid;
67
+ grid-template-columns: 1fr 1fr;
68
+ gap: 30px;
69
+ margin-bottom: 30px;
70
+ }
71
+
72
+ .file-upload-box input[type="file"] {
73
+ position: absolute;
74
+ opacity: 0;
75
+ width: 100%;
76
+ height: 100%;
77
+ cursor: pointer;
78
+ pointer-events: none; /* This prevents double triggering */
79
+ }
80
+
81
+ .file-upload-box:hover {
82
+ border-color: #764ba2;
83
+ transform: translateY(-2px);
84
+ box-shadow: 0 10px 25px rgba(0,0,0,0.1);
85
+ }
86
+
87
+ .file-upload-box.dragover {
88
+ border-color: #764ba2;
89
+ background-color: #f8f9ff;
90
+ }
91
+
92
+ .file-upload-box input[type="file"] {
93
+ position: absolute;
94
+ opacity: 0;
95
+ width: 100%;
96
+ height: 100%;
97
+ cursor: pointer;
98
+ }
99
+
100
+ .upload-icon {
101
+ font-size: 3rem;
102
+ color: #667eea;
103
+ margin-bottom: 15px;
104
+ }
105
+
106
+ .upload-text {
107
+ color: #666;
108
+ font-size: 1rem;
109
+ margin-bottom: 5px;
110
+ }
111
+
112
+ .file-name {
113
+ color: #333;
114
+ font-weight: 600;
115
+ font-size: 0.9rem;
116
+ margin-top: 10px;
117
+ padding: 8px 12px;
118
+ background: #e8f2ff;
119
+ border-radius: 8px;
120
+ display: none;
121
+ }
122
+
123
+ .generate-btn {
124
+ width: 100%;
125
+ padding: 15px;
126
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
127
+ color: white;
128
+ border: none;
129
+ border-radius: 12px;
130
+ font-size: 1.1rem;
131
+ font-weight: 600;
132
+ cursor: pointer;
133
+ transition: all 0.3s ease;
134
+ position: relative;
135
+ overflow: hidden;
136
+ }
137
+
138
+ .generate-btn:hover {
139
+ transform: translateY(-2px);
140
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
141
+ }
142
+
143
+ .generate-btn:disabled {
144
+ opacity: 0.6;
145
+ cursor: not-allowed;
146
+ transform: none;
147
+ }
148
+
149
+ .loading-spinner {
150
+ display: none;
151
+ width: 20px;
152
+ height: 20px;
153
+ border: 2px solid #ffffff;
154
+ border-top: 2px solid transparent;
155
+ border-radius: 50%;
156
+ animation: spin 1s linear infinite;
157
+ margin-right: 10px;
158
+ }
159
+
160
+ @keyframes spin {
161
+ 0% { transform: rotate(0deg); }
162
+ 100% { transform: rotate(360deg); }
163
+ }
164
+
165
+ .result-section {
166
+ padding: 40px;
167
+ background: #f8f9fa;
168
+ display: none;
169
+ }
170
+
171
+ .result-header {
172
+ display: flex;
173
+ justify-content: space-between;
174
+ align-items: center;
175
+ margin-bottom: 20px;
176
+ }
177
+
178
+ .result-title {
179
+ font-size: 1.5rem;
180
+ color: #333;
181
+ font-weight: 600;
182
+ }
183
+
184
+ .download-btn {
185
+ padding: 10px 20px;
186
+ background: #28a745;
187
+ color: white;
188
+ border: none;
189
+ border-radius: 8px;
190
+ font-weight: 600;
191
+ cursor: pointer;
192
+ transition: all 0.3s ease;
193
+ }
194
+
195
+ .download-btn:hover {
196
+ background: #218838;
197
+ transform: translateY(-1px);
198
+ }
199
+
200
+ .test-case-content {
201
+ background: white;
202
+ border-radius: 12px;
203
+ padding: 30px;
204
+ box-shadow: 0 5px 15px rgba(0,0,0,0.08);
205
+ white-space: pre-wrap;
206
+ font-family: 'Courier New', monospace;
207
+ font-size: 0.9rem;
208
+ line-height: 1.6;
209
+ color: #333;
210
+ max-height: 600px;
211
+ overflow-y: auto;
212
+ border: 1px solid #e9ecef;
213
+ }
214
+
215
+ .error-message {
216
+ background: #f8d7da;
217
+ color: #721c24;
218
+ padding: 15px;
219
+ border-radius: 8px;
220
+ margin: 20px 0;
221
+ border: 1px solid #f5c6cb;
222
+ display: none;
223
+ }
224
+
225
+ .success-message {
226
+ background: #d4edda;
227
+ color: #155724;
228
+ padding: 15px;
229
+ border-radius: 8px;
230
+ margin: 20px 0;
231
+ border: 1px solid #c3e6cb;
232
+ display: none;
233
+ }
234
+
235
+ @media (max-width: 768px) {
236
+ .header h1 {
237
+ font-size: 2rem;
238
+ }
239
+
240
+ .file-upload-container {
241
+ grid-template-columns: 1fr;
242
+ gap: 20px;
243
+ }
244
+
245
+ .form-section,
246
+ .result-section {
247
+ padding: 20px;
248
+ }
249
+
250
+ .result-header {
251
+ flex-direction: column;
252
+ gap: 15px;
253
+ align-items: stretch;
254
+ }
255
+ }
256
+
257
+ .pulse {
258
+ animation: pulse 2s infinite;
259
+ }
260
+
261
+ @keyframes pulse {
262
+ 0% {
263
+ transform: scale(1);
264
+ }
265
+ 50% {
266
+ transform: scale(1.02);
267
+ }
268
+ 100% {
269
+ transform: scale(1);
270
+ }
271
+ }
272
+ </style>
273
+ </head>
274
+ <body>
275
+ <div class="container">
276
+ <div class="header">
277
+ <h1>🚀 Aeronix</h1>
278
+ <p>Advanced PCB Test Case Generator</p>
279
+ </div>
280
+
281
+ <div class="main-card">
282
+ <div class="form-section">
283
+ <h2 class="form-title">Upload Your Files</h2>
284
+
285
+ <form id="testCaseForm">
286
+ <div class="file-upload-container">
287
+ <div class="file-upload-box" id="manualUpload">
288
+ <input type="file" id="manualFile" accept=".docx,.pdf,.doc" required>
289
+ <div class="upload-icon">📋</div>
290
+ <div class="upload-text">Manual Document</div>
291
+ <div class="upload-text" style="font-size: 0.8rem; opacity: 0.7;">DOCX, PDF, DOC</div>
292
+ <div class="file-name" id="manualFileName"></div>
293
+ </div>
294
+
295
+ <div class="file-upload-box" id="ipcUpload">
296
+ <input type="file" id="ipcFile" accept=".ipc" required>
297
+ <div class="upload-icon">🔌</div>
298
+ <div class="upload-text">IPC File</div>
299
+ <div class="upload-text" style="font-size: 0.8rem; opacity: 0.7;">IPC format</div>
300
+ <div class="file-name" id="ipcFileName"></div>
301
+ </div>
302
+ </div>
303
+
304
+ <button type="submit" class="generate-btn" id="generateBtn">
305
+ <span class="loading-spinner" id="loadingSpinner"></span>
306
+ <span id="btnText">Generate Test Cases</span>
307
+ </button>
308
+ </form>
309
+
310
+ <div class="error-message" id="errorMessage"></div>
311
+ <div class="success-message" id="successMessage"></div>
312
+ </div>
313
+
314
+ <div class="result-section" id="resultSection">
315
+ <div class="result-header">
316
+ <h3 class="result-title">Generated Test Cases</h3>
317
+ <button class="download-btn" id="downloadBtn">💾 Download</button>
318
+ </div>
319
+ <div class="test-case-content" id="testCaseContent"></div>
320
+ </div>
321
+ </div>
322
+ </div>
323
+
324
+ <script>
325
+ const API_BASE_URL = 'http://localhost:8000';
326
+
327
+ // File upload handling
328
+ function setupFileUpload(uploadBoxId, fileInputId, fileNameId) {
329
+ const uploadBox = document.getElementById(uploadBoxId);
330
+ const fileInput = document.getElementById(fileInputId);
331
+ const fileName = document.getElementById(fileNameId);
332
+
333
+ uploadBox.addEventListener('click', () => fileInput.click());
334
+
335
+ fileInput.addEventListener('change', (e) => {
336
+ const file = e.target.files[0];
337
+ if (file) {
338
+ fileName.textContent = file.name;
339
+ fileName.style.display = 'block';
340
+ uploadBox.classList.add('pulse');
341
+ setTimeout(() => uploadBox.classList.remove('pulse'), 1000);
342
+ }
343
+ });
344
+
345
+ // Drag and drop
346
+ uploadBox.addEventListener('dragover', (e) => {
347
+ e.preventDefault();
348
+ uploadBox.classList.add('dragover');
349
+ });
350
+
351
+ uploadBox.addEventListener('dragleave', () => {
352
+ uploadBox.classList.remove('dragover');
353
+ });
354
+
355
+ uploadBox.addEventListener('drop', (e) => {
356
+ e.preventDefault();
357
+ uploadBox.classList.remove('dragover');
358
+
359
+ const files = e.dataTransfer.files;
360
+ if (files.length > 0) {
361
+ fileInput.files = files;
362
+ const file = files[0];
363
+ fileName.textContent = file.name;
364
+ fileName.style.display = 'block';
365
+ }
366
+ });
367
+ }
368
+
369
+ // Initialize file uploads
370
+ setupFileUpload('manualUpload', 'manualFile', 'manualFileName');
371
+ setupFileUpload('ipcUpload', 'ipcFile', 'ipcFileName');
372
+
373
+ // Form submission
374
+ document.getElementById('testCaseForm').addEventListener('submit', async (e) => {
375
+ e.preventDefault();
376
+
377
+ const manualFile = document.getElementById('manualFile').files[0];
378
+ const ipcFile = document.getElementById('ipcFile').files[0];
379
+
380
+ if (!manualFile || !ipcFile) {
381
+ showError('Please select both files before generating test cases.');
382
+ return;
383
+ }
384
+
385
+ await generateTestCases(manualFile, ipcFile);
386
+ });
387
+
388
+ async function generateTestCases(manualFile, ipcFile) {
389
+ const generateBtn = document.getElementById('generateBtn');
390
+ const loadingSpinner = document.getElementById('loadingSpinner');
391
+ const btnText = document.getElementById('btnText');
392
+ const resultSection = document.getElementById('resultSection');
393
+ const testCaseContent = document.getElementById('testCaseContent');
394
+
395
+ // Show loading state
396
+ generateBtn.disabled = true;
397
+ loadingSpinner.style.display = 'inline-block';
398
+ btnText.textContent = 'Generating...';
399
+ hideMessages();
400
+
401
+ try {
402
+ const formData = new FormData();
403
+ formData.append('manual_file', manualFile);
404
+ formData.append('ipc_file', ipcFile);
405
+
406
+ const response = await fetch('/generate-test-case', {
407
+ method: 'POST',
408
+ body: formData
409
+ });
410
+
411
+ console.log('Response status:', response.status);
412
+ console.log('Response headers:', response.headers.get('content-type'));
413
+
414
+ // Check if response is ok
415
+ if (!response.ok) {
416
+ let errorMessage = `HTTP error! status: ${response.status}`;
417
+
418
+ // Try to get error details
419
+ try {
420
+ const contentType = response.headers.get('content-type');
421
+ if (contentType && contentType.includes('application/json')) {
422
+ const errorData = await response.json();
423
+ errorMessage = errorData.detail || errorMessage;
424
+ } else {
425
+ const errorText = await response.text();
426
+ console.log('Error response text:', errorText);
427
+ errorMessage = `Server error: ${response.status}`;
428
+ }
429
+ } catch (e) {
430
+ console.log('Could not parse error response:', e);
431
+ }
432
+
433
+ throw new Error(errorMessage);
434
+ }
435
+
436
+ // Check content type before parsing
437
+ const contentType = response.headers.get('content-type');
438
+ console.log('Success response content-type:', contentType);
439
+
440
+ let data;
441
+
442
+ if (contentType && contentType.includes('application/json')) {
443
+ // Parse as JSON
444
+ data = await response.json();
445
+ console.log('Parsed JSON data:', data);
446
+
447
+ if (!data.success) {
448
+ throw new Error(data.message || 'Failed to generate test cases');
449
+ }
450
+
451
+ // Check if HTML file is available
452
+ if (data.html_url) {
453
+ console.log('HTML file available at:', data.html_url);
454
+
455
+ // Redirect to the generated HTML page
456
+ showSuccess(`Test cases generated successfully! Redirecting to HTML report...`);
457
+
458
+ // Wait 1 second then redirect
459
+ setTimeout(() => {
460
+ window.location.href = data.html_url;
461
+ }, 1000);
462
+
463
+ return; // Exit function after redirect
464
+ }
465
+
466
+ // If no HTML, show text content (fallback)
467
+ const testCases = data.content;
468
+ window.currentTestCases = testCases;
469
+ window.currentFileName = data.filename || 'test_cases.txt';
470
+
471
+ // Display results on webpage
472
+ testCaseContent.textContent = testCases;
473
+ resultSection.style.display = 'block';
474
+ resultSection.scrollIntoView({ behavior: 'smooth' });
475
+
476
+ } else if (contentType && contentType.includes('text/plain')) {
477
+ // Handle as plain text (fallback)
478
+ const testCases = await response.text();
479
+ console.log('Plain text response received');
480
+
481
+ data = {
482
+ content: testCases,
483
+ filename: response.headers.get('X-Generated-File') || 'test_cases.txt'
484
+ };
485
+
486
+ window.currentTestCases = testCases;
487
+ window.currentFileName = data.filename;
488
+
489
+ // Display results on webpage
490
+ testCaseContent.textContent = data.content;
491
+ resultSection.style.display = 'block';
492
+ resultSection.scrollIntoView({ behavior: 'smooth' });
493
+
494
+ } else {
495
+ // Unknown content type
496
+ const responseText = await response.text();
497
+ console.log('Unknown content type. Response:', responseText);
498
+ throw new Error('Unexpected response format from server');
499
+ }
500
+
501
+ showSuccess(`Test cases generated successfully! File: ${data.filename || 'Generated'}`);
502
+
503
+ } catch (error) {
504
+ console.error('Detailed error:', error);
505
+ showError(error.message || 'An error occurred while generating test cases.');
506
+ } finally {
507
+ // Reset button state
508
+ generateBtn.disabled = false;
509
+ loadingSpinner.style.display = 'none';
510
+ btnText.textContent = 'Generate Test Cases';
511
+ }
512
+ }
513
+
514
+ function showError(message) {
515
+ const errorDiv = document.getElementById('errorMessage');
516
+ errorDiv.textContent = message;
517
+ errorDiv.style.display = 'block';
518
+ setTimeout(() => {
519
+ errorDiv.style.display = 'none';
520
+ }, 5000);
521
+ }
522
+
523
+ function showSuccess(message) {
524
+ const successDiv = document.getElementById('successMessage');
525
+ successDiv.textContent = message;
526
+ successDiv.style.display = 'block';
527
+ setTimeout(() => {
528
+ successDiv.style.display = 'none';
529
+ }, 3000);
530
+ }
531
+
532
+ function hideMessages() {
533
+ document.getElementById('errorMessage').style.display = 'none';
534
+ document.getElementById('successMessage').style.display = 'none';
535
+ }
536
+ </script>
537
+ </body>
538
+ </html>