test-reporting 3.6.4__tar.gz → 3.7.0__tar.gz

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.
Files changed (21) hide show
  1. {test_reporting-3.6.4/test_reporting.egg-info → test_reporting-3.7.0}/PKG-INFO +1 -1
  2. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/templates/project.html +99 -12
  3. {test_reporting-3.6.4 → test_reporting-3.7.0}/setup.py +1 -1
  4. {test_reporting-3.6.4 → test_reporting-3.7.0/test_reporting.egg-info}/PKG-INFO +1 -1
  5. {test_reporting-3.6.4 → test_reporting-3.7.0}/LICENSE +0 -0
  6. {test_reporting-3.6.4 → test_reporting-3.7.0}/README.md +0 -0
  7. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/__init__.py +0 -0
  8. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/classifier.py +0 -0
  9. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/cli.py +0 -0
  10. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/config.py +0 -0
  11. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/plugin.py +0 -0
  12. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/publisher.py +0 -0
  13. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/storage.py +0 -0
  14. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/templates/index.html +0 -0
  15. {test_reporting-3.6.4 → test_reporting-3.7.0}/reporting/templates/run.html +0 -0
  16. {test_reporting-3.6.4 → test_reporting-3.7.0}/setup.cfg +0 -0
  17. {test_reporting-3.6.4 → test_reporting-3.7.0}/test_reporting.egg-info/SOURCES.txt +0 -0
  18. {test_reporting-3.6.4 → test_reporting-3.7.0}/test_reporting.egg-info/dependency_links.txt +0 -0
  19. {test_reporting-3.6.4 → test_reporting-3.7.0}/test_reporting.egg-info/entry_points.txt +0 -0
  20. {test_reporting-3.6.4 → test_reporting-3.7.0}/test_reporting.egg-info/requires.txt +0 -0
  21. {test_reporting-3.6.4 → test_reporting-3.7.0}/test_reporting.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: test-reporting
3
- Version: 3.6.4
3
+ Version: 3.7.0
4
4
  Summary: Multi-project test reporting dashboard — collect results locally or push to S3
5
5
  Home-page: https://github.com/amahdy77/test-reporting.git
6
6
  Author: Ashfaqur Mahdy
@@ -241,10 +241,14 @@
241
241
  .suite-row { display: flex; align-items: center; gap: 14px; padding: 12px 20px;
242
242
  border-top: 1px solid var(--border); cursor: pointer; }
243
243
  .suite-row:hover .suite-name { text-decoration: underline; color: var(--blue); }
244
- .suite-name { font-weight: 600; font-size: 14px; flex: 1; }
244
+ .suite-name { font-weight: 600; font-size: 14px; flex: 1; display: flex; align-items: center; gap: 8px; }
245
245
  .suite-meta { font-size: 12px; color: var(--muted); }
246
246
  .suite-bar { flex: 0 0 120px; }
247
247
  .suite-rate { font-size: 15px; font-weight: 700; flex: 0 0 48px; text-align: right; }
248
+ .run-count-badge { display: inline-flex; align-items: center; justify-content: center;
249
+ background: var(--purple-bg); color: var(--purple); font-size: 11px;
250
+ font-weight: 700; padding: 2px 7px; border-radius: 10px;
251
+ min-width: 20px; flex-shrink: 0; }
248
252
 
249
253
  /* ── Heatmap calendar ── */
250
254
  .heatmap-wrap { overflow-x: auto; }
@@ -301,6 +305,14 @@
301
305
  /* ── Empty state ── */
302
306
  .empty-section { color: var(--muted); font-size: 14px; padding: 16px 0; text-align: center; }
303
307
 
308
+ /* ── Search input ── */
309
+ .search-wrap { padding: 16px 24px; border-bottom: 1px solid var(--border); }
310
+ .search-input { width: 100%; padding: 10px 14px; border: 1px solid var(--border);
311
+ border-radius: 8px; font-size: 14px; background: var(--bg);
312
+ color: var(--text); transition: border-color .15s; }
313
+ .search-input:focus { outline: none; border-color: var(--blue); }
314
+ .search-input::placeholder { color: var(--muted); }
315
+
304
316
  /* Custom tooltip */
305
317
  [data-tooltip] { position: relative; }
306
318
  [data-tooltip]::after {
@@ -541,33 +553,75 @@
541
553
  : regEntries.map(function(reg, i) {
542
554
  const rc2 = rateColor(reg.pass_rate);
543
555
  const total = lastReg ? lastReg.total_tests || 1 : 1;
544
- const fileRows = (reg.suites || []).map(function(s) {
545
- const passed = s.total_tests - s.failed - (s.skipped || 0);
546
- const failedPct = s.total_tests > 0 ? (s.failed / s.total_tests * 100) : 0;
547
- const skippedPct = s.total_tests > 0 ? ((s.skipped || 0) / s.total_tests * 100) : 0;
556
+
557
+ // Group suites by name to detect duplicates
558
+ const suiteGroups = {};
559
+ (reg.suites || []).forEach(function(s) {
560
+ if (!suiteGroups[s.suite]) {
561
+ suiteGroups[s.suite] = [];
562
+ }
563
+ suiteGroups[s.suite].push(s);
564
+ });
565
+
566
+ const fileRows = Object.keys(suiteGroups).map(function(suiteName) {
567
+ const runs = suiteGroups[suiteName];
568
+ const runCount = runs.length;
569
+
570
+ // Calculate accumulated averages
571
+ let totalTests = 0;
572
+ let totalFailed = 0;
573
+ let totalSkipped = 0;
574
+ let totalPassed = 0;
575
+ let avgPassRate = 0;
576
+
577
+ runs.forEach(function(run) {
578
+ totalTests += run.total_tests;
579
+ totalFailed += run.failed;
580
+ totalSkipped += (run.skipped || 0);
581
+ totalPassed += (run.total_tests - run.failed - (run.skipped || 0));
582
+ avgPassRate += run.pass_rate;
583
+ });
584
+
585
+ avgPassRate = avgPassRate / runCount;
586
+
587
+ // Use first run's ID for navigation
588
+ const firstRunId = runs[0].run_id;
589
+
590
+ const failedPct = totalTests > 0 ? (totalFailed / totalTests * 100) : 0;
591
+ const skippedPct = totalTests > 0 ? (totalSkipped / totalTests * 100) : 0;
548
592
  const passedPct = Math.max(0, 100 - failedPct - skippedPct);
549
- return '<div class="suite-row" onclick="goToRun(\'' + s.run_id + '\')">' +
550
- '<div class="suite-name">' + s.suite + '</div>' +
551
- '<div class="suite-meta">' + s.total_tests + ' tests · ' + s.failed + ' failed</div>' +
593
+
594
+ const runBadge = runCount > 1
595
+ ? '<span class="run-count-badge" title="Ran ' + runCount + ' times">×' + runCount + '</span>'
596
+ : '';
597
+
598
+ const metaText = runCount > 1
599
+ ? totalTests + ' tests total · ' + totalFailed + ' failed · avg across ' + runCount + ' runs'
600
+ : totalTests + ' tests · ' + totalFailed + ' failed';
601
+
602
+ return '<div class="suite-row" onclick="goToRun(\'' + firstRunId + '\')">' +
603
+ '<div class="suite-name"><span>' + suiteName + '</span>' + runBadge + '</div>' +
604
+ '<div class="suite-meta">' + metaText + '</div>' +
552
605
  '<div class="suite-bar">' +
553
- '<div class="stacked-bar" title="Passed: ' + passed + ' | Failed: ' + s.failed + ' | Skipped: ' + (s.skipped || 0) + '">' +
606
+ '<div class="stacked-bar" title="Passed: ' + totalPassed + ' | Failed: ' + totalFailed + ' | Skipped: ' + totalSkipped + (runCount > 1 ? ' (accumulated)' : '') + '">' +
554
607
  '<div class="stacked-green" style="width:' + passedPct.toFixed(1) + '%"></div>' +
555
608
  '<div class="stacked-red" style="width:' + failedPct.toFixed(1) + '%"></div>' +
556
609
  '<div class="stacked-grey" style="width:' + skippedPct.toFixed(1) + '%"></div>' +
557
610
  '</div>' +
558
611
  '</div>' +
559
- '<div class="suite-rate ' + rateColor(s.pass_rate) + '">' + s.pass_rate.toFixed(0) + '%</div>' +
612
+ '<div class="suite-rate ' + rateColor(avgPassRate) + '">' + avgPassRate.toFixed(0) + '%</div>' +
560
613
  '</div>';
561
614
  }).join('');
562
615
 
563
616
  const isOpen = i === 0;
564
617
  const regDateTime = reg.timestamp ? fmtDateTime(reg.timestamp) : '';
565
618
  const regTitle = regDateTime ? reg.tag + ' · ' + regDateTime : reg.tag;
619
+ const uniqueSuiteCount = Object.keys(suiteGroups).length;
566
620
  return '<div class="regression">' +
567
621
  '<div class="reg-head" onclick="toggleReg(this)">' +
568
622
  '<div>' +
569
623
  '<div class="reg-title">' + regTitle + '</div>' +
570
- '<div class="reg-sub">' + reg.suites.length + ' test ' + plural(reg.suites.length, 'file') + ' · ' + reg.total_tests + ' tests</div>' +
624
+ '<div class="reg-sub">' + uniqueSuiteCount + ' test ' + plural(uniqueSuiteCount, 'file') + ' · ' + reg.total_tests + ' tests</div>' +
571
625
  '</div>' +
572
626
  '<div class="reg-right">' +
573
627
  '<span class="' + rc2 + '">' + reg.pass_rate.toFixed(0) + '% passing</span>' +
@@ -947,7 +1001,10 @@
947
1001
  return '<div class="section">' +
948
1002
  '<div class="section-head">' +
949
1003
  '<h3>All Test File Runs</h3>' +
950
- '<span style="font-size:13px;color:var(--muted)">' + recentRuns.length + ' recent runs across ' + names.length + ' test ' + plural(names.length, 'file') + '</span>' +
1004
+ '<span style="font-size:13px;color:var(--muted)"><span id="visibleRunCount">' + recentRuns.length + '</span> of ' + recentRuns.length + ' runs across ' + names.length + ' test ' + plural(names.length, 'file') + '</span>' +
1005
+ '</div>' +
1006
+ '<div class="search-wrap">' +
1007
+ '<input type="text" id="historySearch" class="search-input" placeholder="Search by test file name..." oninput="filterHistory()" />' +
951
1008
  '</div>' +
952
1009
  '<div class="section-body-flush">' +
953
1010
  '<table class="hist-table" id="historyTable">' +
@@ -1012,6 +1069,36 @@
1012
1069
  renderHistoryTableBody();
1013
1070
  }
1014
1071
 
1072
+ function filterHistory() {
1073
+ const searchInput = document.getElementById('historySearch');
1074
+ if (!searchInput) return;
1075
+
1076
+ const searchTerm = searchInput.value.toLowerCase();
1077
+ const tbody = document.getElementById('historyTableBody');
1078
+ if (!tbody) return;
1079
+
1080
+ const rows = tbody.querySelectorAll('tr');
1081
+ let visibleCount = 0;
1082
+
1083
+ rows.forEach(function(row) {
1084
+ const fileNameCell = row.querySelector('td:nth-child(3)');
1085
+ if (fileNameCell) {
1086
+ const fileName = fileNameCell.textContent.toLowerCase();
1087
+ if (fileName.includes(searchTerm)) {
1088
+ row.style.display = '';
1089
+ visibleCount++;
1090
+ } else {
1091
+ row.style.display = 'none';
1092
+ }
1093
+ }
1094
+ });
1095
+
1096
+ const countEl = document.getElementById('visibleRunCount');
1097
+ if (countEl) {
1098
+ countEl.textContent = visibleCount;
1099
+ }
1100
+ }
1101
+
1015
1102
  function renderHistoryTableBody() {
1016
1103
  const sparklineIds = {};
1017
1104
  const rows = historyData.runs.map(function(run, i) {
@@ -9,7 +9,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
9
9
 
10
10
  setup(
11
11
  name='test-reporting',
12
- version='3.6.4',
12
+ version='3.7.0',
13
13
  description='Multi-project test reporting dashboard — collect results locally or push to S3',
14
14
  long_description=long_description,
15
15
  long_description_content_type="text/markdown",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: test-reporting
3
- Version: 3.6.4
3
+ Version: 3.7.0
4
4
  Summary: Multi-project test reporting dashboard — collect results locally or push to S3
5
5
  Home-page: https://github.com/amahdy77/test-reporting.git
6
6
  Author: Ashfaqur Mahdy
File without changes
File without changes
File without changes