k6-modern-reporter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,847 @@
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>K6 Performance Test Report - 2026-01-31 16:39</title>
8
+ <!-- Font Awesome for icons -->
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
10
+ <style>
11
+ /* ========================================
12
+ GLOBAL STYLES
13
+ ======================================== */
14
+
15
+ /* Reset default browser styles */
16
+ * {
17
+ margin: 0;
18
+ padding: 0;
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ /* Main body styling with gradient background */
23
+ body {
24
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
25
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
26
+ color: #333;
27
+ line-height: 1.6;
28
+ padding: 20px;
29
+ min-height: 100vh;
30
+ }
31
+
32
+ /* Main container with white background and shadow */
33
+ .container {
34
+ max-width: 1400px;
35
+ margin: 0 auto;
36
+ background: white;
37
+ border-radius: 20px;
38
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
39
+ overflow: hidden;
40
+ }
41
+
42
+ /* ========================================
43
+ HEADER SECTION
44
+ ======================================== */
45
+
46
+ /* Header with dynamic gradient based on test pass/fail status */
47
+ .header {
48
+ background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%);
49
+ color: white;
50
+ padding: 40px;
51
+ position: relative;
52
+ overflow: hidden;
53
+ }
54
+
55
+ /* Animated background effect in header */
56
+ .header::before {
57
+ content: '';
58
+ position: absolute;
59
+ top: -50%;
60
+ right: -50%;
61
+ width: 200%;
62
+ height: 200%;
63
+ background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
64
+ animation: pulse 15s ease-in-out infinite;
65
+ }
66
+
67
+ /* Pulse animation for header background */
68
+ @keyframes pulse {
69
+ 0%, 100% { transform: scale(1); opacity: 0.5; }
70
+ 50% { transform: scale(1.1); opacity: 0.8; }
71
+ }
72
+
73
+ /* Header content positioned above the animated background */
74
+ .header-content {
75
+ position: relative;
76
+ z-index: 10;
77
+ }
78
+
79
+ /* Main heading with flexbox for logo alignment */
80
+ .header h1 {
81
+ font-size: 2.5em;
82
+ margin-bottom: 10px;
83
+ font-weight: 300;
84
+ display: flex;
85
+ align-items: center;
86
+ gap: 15px;
87
+ }
88
+
89
+ /* K6 logo container */
90
+ .k6-logo {
91
+ width: 60px;
92
+ height: 60px;
93
+ background: rgba(255, 255, 255, 0.2);
94
+ border-radius: 12px;
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ font-size: 2em;
99
+ }
100
+
101
+ /* Test status badge (PASSED/FAILED) */
102
+ .test-status {
103
+ display: inline-block;
104
+ padding: 10px 25px;
105
+ border-radius: 50px;
106
+ font-size: 0.9em;
107
+ font-weight: 600;
108
+ margin-top: 15px;
109
+ background: rgba(255, 255, 255, 0.3);
110
+ backdrop-filter: blur(10px);
111
+ }
112
+
113
+ /* ========================================
114
+ STATS GRID SECTION
115
+ ======================================== */
116
+
117
+ /* Responsive grid for statistic cards */
118
+ .stats-grid {
119
+ display: grid;
120
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
121
+ gap: 25px;
122
+ padding: 40px;
123
+ background: #f8f9fa;
124
+ }
125
+
126
+ /* Individual stat card with shadow and hover effects */
127
+ .stat-card {
128
+ background: white;
129
+ border-radius: 15px;
130
+ padding: 30px;
131
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
132
+ transition: all 0.3s ease;
133
+ position: relative;
134
+ overflow: hidden;
135
+ }
136
+
137
+ /* Colored top border for each stat card */
138
+ .stat-card::before {
139
+ content: '';
140
+ position: absolute;
141
+ top: 0;
142
+ left: 0;
143
+ width: 100%;
144
+ height: 4px;
145
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
146
+ }
147
+
148
+ /* Hover effect: lift the card */
149
+ .stat-card:hover {
150
+ transform: translateY(-5px);
151
+ box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15);
152
+ }
153
+
154
+ /* Success state: green gradient */
155
+ .stat-card.success::before {
156
+ background: linear-gradient(90deg, #11998e 0%, #38ef7d 100%);
157
+ }
158
+
159
+ /* Error state: red gradient */
160
+ .stat-card.error::before {
161
+ background: linear-gradient(90deg, #eb3349 0%, #f45c43 100%);
162
+ }
163
+
164
+ /* Warning state: yellow/orange gradient */
165
+ .stat-card.warning::before {
166
+ background: linear-gradient(90deg, #f2994a 0%, #f2c94c 100%);
167
+ }
168
+
169
+ /* Background icon for stat cards (low opacity) */
170
+ .stat-icon {
171
+ font-size: 3em;
172
+ opacity: 0.1;
173
+ position: absolute;
174
+ right: 20px;
175
+ top: 50%;
176
+ transform: translateY(-50%);
177
+ }
178
+
179
+ /* Label text for each statistic */
180
+ .stat-label {
181
+ font-size: 0.85em;
182
+ color: #6c757d;
183
+ text-transform: uppercase;
184
+ letter-spacing: 1px;
185
+ margin-bottom: 10px;
186
+ font-weight: 600;
187
+ }
188
+
189
+ /* Main value display for each statistic */
190
+ .stat-value {
191
+ font-size: 2.5em;
192
+ font-weight: 700;
193
+ color: #2c3e50;
194
+ position: relative;
195
+ z-index: 10;
196
+ }
197
+
198
+ /* Subtext below the main stat value */
199
+ .stat-subtext {
200
+ font-size: 0.9em;
201
+ color: #95a5a6;
202
+ margin-top: 8px;
203
+ }
204
+
205
+ /* ========================================
206
+ TABS SECTION
207
+ ======================================== */
208
+
209
+ /* Container for all tab content */
210
+ .tabs-container {
211
+ padding: 40px;
212
+ }
213
+
214
+ /* Tab button container with bottom border */
215
+ .tabs {
216
+ display: flex;
217
+ gap: 10px;
218
+ border-bottom: 2px solid #e9ecef;
219
+ margin-bottom: 30px;
220
+ flex-wrap: wrap;
221
+ }
222
+
223
+ /* Individual tab button styling */
224
+ .tab-button {
225
+ padding: 15px 30px;
226
+ background: none;
227
+ border: none;
228
+ cursor: pointer;
229
+ font-size: 1em;
230
+ font-weight: 600;
231
+ color: #6c757d;
232
+ border-bottom: 3px solid transparent;
233
+ transition: all 0.3s ease;
234
+ display: flex;
235
+ align-items: center;
236
+ gap: 10px;
237
+ }
238
+
239
+ /* Tab button hover state */
240
+ .tab-button:hover {
241
+ color: #667eea;
242
+ background: rgba(102, 126, 234, 0.1);
243
+ }
244
+
245
+ /* Active tab styling */
246
+ .tab-button.active {
247
+ color: #667eea;
248
+ border-bottom-color: #667eea;
249
+ }
250
+
251
+ /* Tab content panel (hidden by default) */
252
+ .tab-content {
253
+ display: none;
254
+ animation: fadeIn 0.5s ease;
255
+ }
256
+
257
+ /* Show active tab content */
258
+ .tab-content.active {
259
+ display: block;
260
+ }
261
+
262
+ /* Fade-in animation for tab content */
263
+ @keyframes fadeIn {
264
+ from { opacity: 0; transform: translateY(10px); }
265
+ to { opacity: 1; transform: translateY(0); }
266
+ }
267
+
268
+ /* ========================================
269
+ METRICS TABLE
270
+ ======================================== */
271
+
272
+ /* Main metrics table with rounded corners */
273
+ .metrics-table {
274
+ width: 100%;
275
+ border-collapse: separate;
276
+ border-spacing: 0;
277
+ border-radius: 10px;
278
+ overflow: hidden;
279
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
280
+ }
281
+
282
+ /* Table header with gradient background */
283
+ .metrics-table thead {
284
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
285
+ color: white;
286
+ }
287
+
288
+ /* Table header cells */
289
+ .metrics-table th {
290
+ padding: 15px;
291
+ text-align: left;
292
+ font-weight: 600;
293
+ font-size: 0.9em;
294
+ text-transform: uppercase;
295
+ letter-spacing: 0.5px;
296
+ }
297
+
298
+ /* Table data cells */
299
+ .metrics-table td {
300
+ padding: 15px;
301
+ border-bottom: 1px solid #e9ecef;
302
+ }
303
+
304
+ /* Table row hover effect */
305
+ .metrics-table tbody tr {
306
+ transition: background 0.2s ease;
307
+ }
308
+
309
+ .metrics-table tbody tr:hover {
310
+ background: #f8f9fa;
311
+ }
312
+
313
+ /* Remove border from last row */
314
+ .metrics-table tbody tr:last-child td {
315
+ border-bottom: none;
316
+ }
317
+
318
+ /* ========================================
319
+ BADGES AND INDICATORS
320
+ ======================================== */
321
+
322
+ /* Generic badge styling */
323
+ .badge {
324
+ display: inline-block;
325
+ padding: 5px 12px;
326
+ border-radius: 20px;
327
+ font-size: 0.85em;
328
+ font-weight: 600;
329
+ }
330
+
331
+ /* Success badge (green) */
332
+ .badge-success {
333
+ background: #d4edda;
334
+ color: #155724;
335
+ }
336
+
337
+ /* Error badge (red) */
338
+ .badge-error {
339
+ background: #f8d7da;
340
+ color: #721c24;
341
+ }
342
+
343
+ /* Warning badge (yellow) */
344
+ .badge-warning {
345
+ background: #fff3cd;
346
+ color: #856404;
347
+ }
348
+
349
+ /* Good metric value (green text) */
350
+ .metric-value-good {
351
+ color: #28a745;
352
+ font-weight: 600;
353
+ }
354
+
355
+ /* Bad metric value (red text) */
356
+ .metric-value-bad {
357
+ color: #dc3545;
358
+ font-weight: 600;
359
+ }
360
+
361
+ /* ========================================
362
+ CHART AND CONTAINER STYLES
363
+ ======================================== */
364
+
365
+ /* Container for charts and content sections */
366
+ .chart-container {
367
+ background: white;
368
+ border-radius: 15px;
369
+ padding: 30px;
370
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
371
+ margin-bottom: 30px;
372
+ }
373
+
374
+ /* Chart section title */
375
+ .chart-title {
376
+ font-size: 1.3em;
377
+ font-weight: 600;
378
+ margin-bottom: 20px;
379
+ color: #2c3e50;
380
+ }
381
+
382
+ /* Progress bar container */
383
+ .progress-bar {
384
+ height: 30px;
385
+ background: #e9ecef;
386
+ border-radius: 15px;
387
+ overflow: hidden;
388
+ margin: 10px 0;
389
+ position: relative;
390
+ }
391
+
392
+ /* Progress bar fill with animation */
393
+ .progress-fill {
394
+ height: 100%;
395
+ background: linear-gradient(90deg, #11998e 0%, #38ef7d 100%);
396
+ border-radius: 15px;
397
+ display: flex;
398
+ align-items: center;
399
+ justify-content: flex-end;
400
+ padding-right: 15px;
401
+ color: white;
402
+ font-weight: 600;
403
+ transition: width 1s ease;
404
+ }
405
+
406
+ /* Error state for progress bar (red gradient) */
407
+ .progress-fill.error {
408
+ background: linear-gradient(90deg, #eb3349 0%, #f45c43 100%);
409
+ }
410
+
411
+ /* ========================================
412
+ FOOTER
413
+ ======================================== */
414
+
415
+ /* Footer section */
416
+ .footer {
417
+ text-align: center;
418
+ padding: 30px;
419
+ background: #f8f9fa;
420
+ color: #6c757d;
421
+ font-size: 0.9em;
422
+ }
423
+
424
+ /* Footer links */
425
+ .footer a {
426
+ color: #667eea;
427
+ text-decoration: none;
428
+ font-weight: 600;
429
+ }
430
+
431
+ .footer a:hover {
432
+ text-decoration: underline;
433
+ }
434
+
435
+ /* ========================================
436
+ RESPONSIVE DESIGN
437
+ ======================================== */
438
+
439
+ /* Mobile/tablet optimizations */
440
+ @media (max-width: 768px) {
441
+ .header h1 {
442
+ font-size: 1.8em;
443
+ }
444
+
445
+ .stats-grid {
446
+ grid-template-columns: 1fr;
447
+ padding: 20px;
448
+ }
449
+
450
+ .tabs-container {
451
+ padding: 20px;
452
+ }
453
+
454
+ .tab-button {
455
+ font-size: 0.9em;
456
+ padding: 12px 20px;
457
+ }
458
+ }
459
+
460
+ /* ========================================
461
+ CHECK ITEMS
462
+ ======================================== */
463
+
464
+ /* Individual check result item */
465
+ .check-item {
466
+ display: flex;
467
+ justify-content: space-between;
468
+ align-items: center;
469
+ padding: 15px;
470
+ background: white;
471
+ border-radius: 10px;
472
+ margin-bottom: 10px;
473
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
474
+ }
475
+
476
+ .check-item:hover {
477
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
478
+ }
479
+
480
+ /* Check name/description */
481
+ .check-name {
482
+ flex: 1;
483
+ font-weight: 500;
484
+ }
485
+
486
+ /* Container for check statistics */
487
+ .check-stats {
488
+ display: flex;
489
+ gap: 20px;
490
+ }
491
+
492
+ /* ========================================
493
+ HEADER SUBTITLE AND METHOD BADGES
494
+ ======================================== */
495
+
496
+ /* Subtitle display in header */
497
+ .header-subtitle {
498
+ font-size: 1.1em;
499
+ opacity: 0.85;
500
+ margin: 15px 0 10px 0;
501
+ font-family: 'Courier New', monospace;
502
+ background: rgba(255, 255, 255, 0.2);
503
+ padding: 10px 20px;
504
+ border-radius: 8px;
505
+ display: inline-block;
506
+ }
507
+
508
+ /* HTTP method badge (GET, POST, etc.) */
509
+ .http-method-badge {
510
+ display: inline-block;
511
+ padding: 5px 15px;
512
+ border-radius: 6px;
513
+ font-weight: 700;
514
+ font-size: 0.9em;
515
+ margin-right: 10px;
516
+ font-family: 'Courier New', monospace;
517
+ letter-spacing: 1px;
518
+ }
519
+
520
+ /* Color coding for different HTTP methods */
521
+ .method-GET {
522
+ background: #28a745;
523
+ color: white;
524
+ }
525
+
526
+ .method-POST {
527
+ background: #007bff;
528
+ color: white;
529
+ }
530
+
531
+ .method-PUT {
532
+ background: #ffc107;
533
+ color: #000;
534
+ }
535
+
536
+ .method-DELETE {
537
+ background: #dc3545;
538
+ color: white;
539
+ }
540
+
541
+ .method-PATCH {
542
+ background: #17a2b8;
543
+ color: white;
544
+ }
545
+
546
+ /* ========================================
547
+ INFO TABLE
548
+ ======================================== */
549
+
550
+ /* Table for displaying test information */
551
+ .info-table {
552
+ width: 100%;
553
+ border-collapse: collapse;
554
+ margin-top: 15px;
555
+ }
556
+
557
+ /* Info table cells */
558
+ .info-table td {
559
+ padding: 10px 15px;
560
+ border-bottom: 1px solid #e9ecef;
561
+ }
562
+
563
+ /* Info table labels (left column) */
564
+ .info-table td:first-child {
565
+ font-weight: 600;
566
+ color: #667eea;
567
+ width: 40%;
568
+ }
569
+
570
+ /* Info table values (right column) */
571
+ .info-table td:last-child {
572
+ color: #2c3e50;
573
+ font-family: 'Courier New', monospace;
574
+ }
575
+
576
+ /* Remove border from last row */
577
+ .info-table tr:last-child td {
578
+ border-bottom: none;
579
+ }
580
+
581
+ /* Row hover effect */
582
+ .info-table tr:hover {
583
+ background: #f8f9fa;
584
+ }
585
+ </style>
586
+ </head>
587
+ <body>
588
+ <div class="container">
589
+ <!-- ========================================
590
+ HEADER SECTION
591
+ ======================================== -->
592
+ <div class="header">
593
+ <div class="header-content">
594
+ <h1>
595
+ <!-- K6 Logo SVG -->
596
+ <div class="k6-logo">
597
+ <svg width="40" height="36" viewBox="0 0 50 45" fill="white">
598
+ <path d="M31.968 34.681a2.007 2.007 0 002.011-2.003c0-1.106-.9-2.003-2.011-2.003a2.007 2.007 0 00-2.012 2.003c0 1.106.9 2.003 2.012 2.003z"/>
599
+ <path d="M39.575 0L27.154 16.883 16.729 9.31 0 45h50L39.575 0zM23.663 37.17l-2.97-4.072v4.072h-2.751V22.038l2.75 1.989v7.66l3.659-5.014 2.086 1.51-3.071 4.21 3.486 4.776h-3.189v.001zm8.305.17c-2.586 0-4.681-2.088-4.681-4.662 0-1.025.332-1.972.896-2.743l4.695-6.435 2.086 1.51-2.239 3.07a4.667 4.667 0 013.924 4.6c0 2.572-2.095 4.66-4.681 4.66z"/>
600
+ </svg>
601
+ </div>
602
+ K6 Performance Test Report
603
+ </h1>
604
+ <!-- Report title -->
605
+ <p style="font-size: 1.2em; opacity: 0.9; margin: 10px 0;">2026-01-31 16:39</p>
606
+ <!-- Subtitle with HTTP method badge if provided -->
607
+
608
+ <span class="test-status">
609
+ ❌ TESTS FAILED
610
+ </span>
611
+
612
+ <!-- Timestamp when report was generated -->
613
+ <p style="margin-top: 15px; opacity: 0.9;">
614
+ <i class="far fa-clock"></i> Generated: 01/31/2026, 11:39:41
615
+ </p>
616
+ </div>
617
+ </div>
618
+
619
+ <!-- ========================================
620
+ STATS GRID - Overview Cards
621
+ ======================================== -->
622
+ <div class="stats-grid">
623
+ <!-- Total Requests Card -->
624
+ <div class="stat-card error">
625
+ <i class="fas fa-globe stat-icon"></i>
626
+ <div class="stat-label">Total Requests</div>
627
+ <div class="stat-value">100</div>
628
+ <div class="stat-subtext">82 successful</div>
629
+ </div>
630
+
631
+ <!-- Success Rate Card -->
632
+ <div class="stat-card error">
633
+ <i class="fas fa-chart-line stat-icon"></i>
634
+ <div class="stat-label">Success Rate</div>
635
+ <div class="stat-value">82.00%</div>
636
+ <div class="stat-subtext">18 failed requests</div>
637
+ </div>
638
+
639
+ <!-- Average Response Time Card -->
640
+ <div class="stat-card success">
641
+ <i class="fas fa-tachometer-alt stat-icon"></i>
642
+ <div class="stat-label">Avg Response Time</div>
643
+ <div class="stat-value">98.99<span style="font-size: 0.5em;">ms</span></div>
644
+ <div class="stat-subtext">P95: 347.91ms</div>
645
+ </div>
646
+
647
+ <!-- Virtual Users Card -->
648
+ <div class="stat-card">
649
+ <i class="fas fa-users stat-icon"></i>
650
+ <div class="stat-label">Virtual Users</div>
651
+ <div class="stat-value">1</div>
652
+ <div class="stat-subtext">Average: 0 VUs</div>
653
+ </div>
654
+
655
+ <!-- Checks Card -->
656
+ <div class="stat-card error">
657
+ <i class="fas fa-check-circle stat-icon"></i>
658
+ <div class="stat-label">Checks</div>
659
+ <div class="stat-value">100</div>
660
+ <div class="stat-subtext">82 passed / 18 failed</div>
661
+ </div>
662
+
663
+ <!-- Thresholds Card -->
664
+ <div class="stat-card error">
665
+ <i class="fas fa-exclamation-triangle stat-icon"></i>
666
+ <div class="stat-label">Thresholds</div>
667
+ <div class="stat-value">2</div>
668
+ <div class="stat-subtext">of 3 breached</div>
669
+ </div>
670
+ </div>
671
+
672
+ <!-- ========================================
673
+ TABS SECTION
674
+ ======================================== -->
675
+ <div class="tabs-container">
676
+ <!-- Tab Navigation Buttons -->
677
+ <div class="tabs">
678
+ <button class="tab-button active" onclick="switchTab(event, 'overview')">
679
+ <i class="fas fa-chart-pie"></i> Overview
680
+ </button>
681
+ <button class="tab-button" onclick="switchTab(event, 'metrics')">
682
+ <i class="fas fa-table"></i> Detailed Metrics
683
+ </button>
684
+ <button class="tab-button" onclick="switchTab(event, 'checks')">
685
+ <i class="fas fa-tasks"></i> Checks & Groups
686
+ </button>
687
+ <button class="tab-button" onclick="switchTab(event, 'thresholds')">
688
+ <i class="fas fa-gauge-high"></i> Thresholds
689
+ </button>
690
+ <!-- Conditional Test Info tab (only if additional info provided) -->
691
+
692
+ </div>
693
+
694
+ <!-- Tab Content Panels -->
695
+
696
+ <!-- Overview Tab - Charts and graphs -->
697
+ <div id="overview" class="tab-content active">
698
+
699
+ <div class="chart-container">
700
+ <h3 class="chart-title">Performance Overview</h3>
701
+
702
+ <!-- Success Rate Progress Bar -->
703
+ <div style="margin: 30px 0;">
704
+ <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
705
+ <span>Success Rate</span>
706
+ <span class="metric-value-good">82.00%</span>
707
+ </div>
708
+ <div class="progress-bar">
709
+ <div class="progress-fill" style="width: 82.00%">82.00%</div>
710
+ </div>
711
+ </div>
712
+
713
+ <!-- Error Rate Progress Bar -->
714
+ <div style="margin: 30px 0;">
715
+ <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
716
+ <span>Error Rate</span>
717
+ <span class="metric-value-bad">18.00%</span>
718
+ </div>
719
+ <div class="progress-bar">
720
+ <div class="progress-fill error" style="width: 18.00%">18.00%</div>
721
+ </div>
722
+ </div>
723
+
724
+ <!-- Response Time Statistics Grid -->
725
+ <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-top: 30px;">
726
+ <!-- Minimum Response Time -->
727
+ <div style="text-align: center; padding: 20px; background: #f8f9fa; border-radius: 10px;">
728
+ <div style="font-size: 0.9em; color: #6c757d; margin-bottom: 5px;">MIN</div>
729
+ <div style="font-size: 1.8em; font-weight: 700; color: #28a745;">35.15ms</div>
730
+ </div>
731
+ <!-- Average Response Time -->
732
+ <div style="text-align: center; padding: 20px; background: #f8f9fa; border-radius: 10px;">
733
+ <div style="font-size: 0.9em; color: #6c757d; margin-bottom: 5px;">AVG</div>
734
+ <div style="font-size: 1.8em; font-weight: 700; color: #667eea;">98.99ms</div>
735
+ </div>
736
+ <!-- 95th Percentile Response Time -->
737
+ <div style="text-align: center; padding: 20px; background: #f8f9fa; border-radius: 10px;">
738
+ <div style="font-size: 0.9em; color: #6c757d; margin-bottom: 5px;">P95</div>
739
+ <div style="font-size: 1.8em; font-weight: 700; color: #f2994a;">347.91ms</div>
740
+ </div>
741
+ <!-- Maximum Response Time -->
742
+ <div style="text-align: center; padding: 20px; background: #f8f9fa; border-radius: 10px;">
743
+ <div style="font-size: 0.9em; color: #6c757d; margin-bottom: 5px;">MAX</div>
744
+ <div style="font-size: 1.8em; font-weight: 700; color: #dc3545;">968.04ms</div>
745
+ </div>
746
+ </div>
747
+ </div>
748
+
749
+ <!-- Data Transfer Statistics -->
750
+ <div class="chart-container">
751
+ <h3 class="chart-title">Data Transfer</h3>
752
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-top: 20px;">
753
+ <!-- Data Received -->
754
+ <div style="text-align: center;">
755
+ <i class="fas fa-download" style="font-size: 3em; color: #667eea; opacity: 0.3;"></i>
756
+ <div style="font-size: 2em; font-weight: 700; margin: 10px 0;">0.13 MB</div>
757
+ <div style="color: #6c757d;">Data Received</div>
758
+ </div>
759
+ <!-- Data Sent -->
760
+ <div style="text-align: center;">
761
+ <i class="fas fa-upload" style="font-size: 3em; color: #764ba2; opacity: 0.3;"></i>
762
+ <div style="font-size: 2em; font-weight: 700; margin: 10px 0;">0.04 MB</div>
763
+ <div style="color: #6c757d;">Data Sent</div>
764
+ </div>
765
+ </div>
766
+ </div>
767
+
768
+ </div>
769
+
770
+ <!-- Metrics Tab - Detailed metrics table -->
771
+ <div id="metrics" class="tab-content">
772
+ <div class="chart-container"><h3 class="chart-title">HTTP Request Metrics</h3><table class="metrics-table"><thead><tr><th>Metric</th><th>Avg</th><th>Min</th><th>Med</th><th>Max</th><th>P90</th><th>P95</th></tr></thead><tbody><tr><td><strong>http_req_duration</strong></td><td>98.99</td><td class="metric-value-good">35.15</td><td>47.76</td><td class="metric-value-bad">968.04</td><td>252.88</td><td>347.91</td></tr><tr><td><strong>http_req_waiting</strong></td><td>98.71</td><td class="metric-value-good">35.15</td><td>47.45</td><td class="metric-value-bad">968.04</td><td>252.19</td><td>347.88</td></tr><tr><td><strong>http_req_connecting</strong></td><td>9.12</td><td class="metric-value-good">0.00</td><td>0.00</td><td class="metric-value-bad">47.01</td><td>44.77</td><td>47.01</td></tr><tr><td><strong>http_req_tls_handshaking</strong></td><td>23.28</td><td class="metric-value-good">0.00</td><td>0.00</td><td class="metric-value-bad">118.89</td><td>116.52</td><td>118.89</td></tr><tr><td><strong>http_req_sending</strong></td><td>0.12</td><td class="metric-value-good">0.00</td><td>0.00</td><td class="metric-value-bad">3.01</td><td>0.51</td><td>0.53</td></tr><tr><td><strong>http_req_receiving</strong></td><td>0.17</td><td class="metric-value-good">0.00</td><td>0.00</td><td class="metric-value-bad">6.79</td><td>0.00</td><td>1.30</td></tr><tr><td><strong>http_req_blocked</strong></td><td>40.23</td><td class="metric-value-good">0.00</td><td>0.00</td><td class="metric-value-bad">205.44</td><td>200.36</td><td>204.16</td></tr><tr><td><strong>iteration_duration</strong></td><td>140.17</td><td class="metric-value-good">35.68</td><td>48.02</td><td class="metric-value-bad">969.07</td><td>310.02</td><td>357.10</td></tr></tbody></table></div><p style="margin-top: 10px; color: #6c757d; font-size: 0.9em;"><i class="fas fa-info-circle"></i> All times are in milliseconds</p>
773
+ </div>
774
+
775
+ <!-- Checks Tab - Test checks and validations -->
776
+ <div id="checks" class="tab-content">
777
+ <div class="chart-container"><h3 class="chart-title"><i class="fas fa-list-check"></i> Other Checks</h3><div class="check-item"><div class="check-name">Response status 200</div><div class="check-stats"><span class="badge badge-success"><i class="fas fa-check"></i> 82 passed</span><span class="badge badge-error"><i class="fas fa-times"></i> 18 failed</span></div></div></div>
778
+ </div>
779
+
780
+ <!-- Thresholds Tab - Threshold pass/fail status -->
781
+ <div id="thresholds" class="tab-content">
782
+ <div class="chart-container">
783
+ <h3 class="chart-title"><i class="fas fa-gauge-high"></i> Threshold Results</h3>
784
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px;">
785
+ <div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 20px; border-radius: 10px; text-align: center;">
786
+ <div style="font-size: 2.5em; font-weight: 700; color: #155724;">1</div>
787
+ <div style="color: #155724; font-weight: 600;">Passed</div>
788
+ </div>
789
+ <div style="background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%); padding: 20px; border-radius: 10px; text-align: center;">
790
+ <div style="font-size: 2.5em; font-weight: 700; color: #721c24;">2</div>
791
+ <div style="color: #721c24; font-weight: 600;">Failed</div>
792
+ </div>
793
+ </div><div class="check-item" style="border-left: 4px solid #dc3545;"><div style="flex: 1;"><div style="font-weight: 600; margin-bottom: 5px;"><i class="fas fa-times-circle" style="color: #dc3545;"></i> checks</div><div style="color: #6c757d; font-size: 0.9em; font-family: monospace;">rate==1.00</div></div><div class="check-stats"><span class="badge badge-error"><i class="fas fa-times"></i> FAILED</span></div></div><div class="check-item" style="border-left: 4px solid #dc3545;"><div style="flex: 1;"><div style="font-weight: 600; margin-bottom: 5px;"><i class="fas fa-times-circle" style="color: #dc3545;"></i> http_req_failed</div><div style="color: #6c757d; font-size: 0.9em; font-family: monospace;">rate==0.00</div></div><div class="check-stats"><span class="badge badge-error"><i class="fas fa-times"></i> FAILED</span></div></div><div class="check-item" style="border-left: 4px solid #28a745;"><div style="flex: 1;"><div style="font-weight: 600; margin-bottom: 5px;"><i class="fas fa-check-circle" style="color: #28a745;"></i> http_req_duration</div><div style="color: #6c757d; font-size: 0.9em; font-family: monospace;">p(95)&lt;1000</div></div><div class="check-stats"><span class="badge badge-success"><i class="fas fa-check"></i> PASSED</span></div></div></div>
794
+ </div>
795
+
796
+ <!-- Test Info Tab - Additional configuration details -->
797
+
798
+ </div>
799
+
800
+ <!-- ========================================
801
+ FOOTER
802
+ ======================================== -->
803
+ <div class="footer">
804
+ <p><strong>K6 Modern Reporter by Samin Azhan</strong></p>
805
+ <p>Generated with ❤️ by K6 Performance Testing Suite</p>
806
+ <p style="margin-top: 10px;">
807
+ <a href="https://github.com/Samin005/k6-modern-reporter" target="_blank">Documentation</a> |
808
+ <a href="https://github.com/Samin005" target="_blank">GitHub</a>
809
+ </p>
810
+ </div>
811
+ </div>
812
+
813
+ <!-- ========================================
814
+ JAVASCRIPT - Tab Switching & Animations
815
+ ======================================== -->
816
+ <script>
817
+ /**
818
+ * Switch between tabs when clicking tab buttons
819
+ * @param {Event} event - The click event
820
+ * @param {string} tabId - The ID of the tab to show
821
+ */
822
+ function switchTab(event, tabId) {
823
+ // Remove active class from all tab buttons
824
+ document.querySelectorAll('.tab-button').forEach(btn => btn.classList.remove('active'));
825
+ // Hide all tab content panels
826
+ document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
827
+
828
+ // Add active class to clicked button
829
+ event.currentTarget.classList.add('active');
830
+ // Show selected tab content
831
+ document.getElementById(tabId).classList.add('active');
832
+ }
833
+
834
+ /**
835
+ * Animate progress bars on page load
836
+ * Progress bars start at 0 width and animate to their final width
837
+ */
838
+ window.addEventListener('load', () => {
839
+ document.querySelectorAll('.progress-fill').forEach(bar => {
840
+ const width = bar.style.width; // Store final width
841
+ bar.style.width = '0'; // Start at 0
842
+ setTimeout(() => { bar.style.width = width; }, 100); // Animate to final width
843
+ });
844
+ });
845
+ </script>
846
+ </body>
847
+ </html>