test-reporting 3.7.3__tar.gz → 3.7.4__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.7.3 → test_reporting-3.7.4}/PKG-INFO +1 -1
  2. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/publisher.py +35 -28
  3. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/templates/project.html +15 -7
  4. {test_reporting-3.7.3 → test_reporting-3.7.4}/setup.py +1 -1
  5. {test_reporting-3.7.3 → test_reporting-3.7.4}/test_reporting.egg-info/PKG-INFO +1 -1
  6. {test_reporting-3.7.3 → test_reporting-3.7.4}/LICENSE +0 -0
  7. {test_reporting-3.7.3 → test_reporting-3.7.4}/README.md +0 -0
  8. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/__init__.py +0 -0
  9. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/classifier.py +0 -0
  10. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/cli.py +0 -0
  11. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/config.py +0 -0
  12. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/plugin.py +0 -0
  13. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/storage.py +0 -0
  14. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/templates/index.html +0 -0
  15. {test_reporting-3.7.3 → test_reporting-3.7.4}/reporting/templates/run.html +0 -0
  16. {test_reporting-3.7.3 → test_reporting-3.7.4}/setup.cfg +0 -0
  17. {test_reporting-3.7.3 → test_reporting-3.7.4}/test_reporting.egg-info/SOURCES.txt +0 -0
  18. {test_reporting-3.7.3 → test_reporting-3.7.4}/test_reporting.egg-info/dependency_links.txt +0 -0
  19. {test_reporting-3.7.3 → test_reporting-3.7.4}/test_reporting.egg-info/entry_points.txt +0 -0
  20. {test_reporting-3.7.3 → test_reporting-3.7.4}/test_reporting.egg-info/requires.txt +0 -0
  21. {test_reporting-3.7.3 → test_reporting-3.7.4}/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.7.3
3
+ Version: 3.7.4
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
@@ -473,7 +473,7 @@ class Publisher:
473
473
  tag = run.get('regression_tag') or self._date_tag(run.get('timestamp'))
474
474
  ts = run.get('timestamp', '')
475
475
 
476
- # Suite summary
476
+ # Suite summary (kept for backwards compatibility)
477
477
  if suite not in suites:
478
478
  suites[suite] = {'name': suite, 'last_run': ts,
479
479
  'last_pass_rate': 0, 'runs': []}
@@ -494,11 +494,7 @@ class Publisher:
494
494
  'duration_seconds': run.get('duration_seconds', 0),
495
495
  })
496
496
 
497
- # Regression grouping
498
- # Strip [TAG] suffix to group reruns with original runs
499
- import re
500
- base_suite = re.sub(r'\s*\[.*?\]\s*$', '', suite)
501
-
497
+ # Regression grouping - group by actual test files, not suite names
502
498
  if tag not in regressions:
503
499
  regressions[tag] = {'tag': tag, 'date': tag[:10], 'suites': [],
504
500
  'total_tests': 0, 'passed': 0, 'failed': 0, 'pass_rate': 0,
@@ -507,28 +503,39 @@ class Publisher:
507
503
  # Track the latest timestamp for this regression
508
504
  if ts > reg.get('timestamp', ''):
509
505
  reg['timestamp'] = ts
510
- existing = next((s for s in reg['suites'] if s['suite'] == base_suite), None)
511
- if existing:
512
- # Accumulate stats for multiple runs of the same test
513
- existing['total_tests'] += run.get('total_tests', 0)
514
- existing['passed'] += run.get('passed', 0)
515
- existing['failed'] += run.get('failed', 0)
516
- existing['run_count'] = existing.get('run_count', 1) + 1
517
- # Update to latest timestamp and run_id
518
- if ts > existing.get('timestamp', ''):
519
- existing['timestamp'] = ts
520
- existing['run_id'] = run.get('run_id')
521
- # Recalculate pass rate based on accumulated totals
522
- if existing['total_tests'] > 0:
523
- existing['pass_rate'] = round((existing['passed'] / existing['total_tests']) * 100, 1)
524
- else:
525
- reg['suites'].append({'suite': base_suite, 'timestamp': ts,
526
- 'run_id': run.get('run_id'),
527
- 'pass_rate': run.get('pass_rate', 0),
528
- 'total_tests': run.get('total_tests', 0),
529
- 'passed': run.get('passed', 0),
530
- 'failed': run.get('failed', 0),
531
- 'run_count': 1})
506
+
507
+ # Process each test file in this run
508
+ for test_file in run.get('test_files', []):
509
+ file_name = test_file.get('file_name', 'unknown')
510
+ # Strip .py extension for consistency
511
+ base_file_name = file_name.replace('.py', '')
512
+
513
+ existing = next((s for s in reg['suites'] if s['suite'] == base_file_name), None)
514
+ if existing:
515
+ # Accumulate stats for multiple runs of the same file
516
+ existing['total_tests'] += test_file.get('total', 0)
517
+ existing['passed'] += test_file.get('passed', 0)
518
+ existing['failed'] += test_file.get('failed', 0)
519
+ existing['run_count'] = existing.get('run_count', 1) + 1
520
+ # Update to latest timestamp and run_id
521
+ if ts > existing.get('timestamp', ''):
522
+ existing['timestamp'] = ts
523
+ existing['run_id'] = run.get('run_id')
524
+ # Recalculate pass rate based on accumulated totals
525
+ if existing['total_tests'] > 0:
526
+ existing['pass_rate'] = round((existing['passed'] / existing['total_tests']) * 100, 1)
527
+ else:
528
+ file_total = test_file.get('total', 0)
529
+ file_passed = test_file.get('passed', 0)
530
+ file_failed = test_file.get('failed', 0)
531
+ file_pass_rate = round((file_passed / file_total * 100) if file_total > 0 else 0, 1)
532
+ reg['suites'].append({'suite': base_file_name, 'timestamp': ts,
533
+ 'run_id': run.get('run_id'),
534
+ 'pass_rate': file_pass_rate,
535
+ 'total_tests': file_total,
536
+ 'passed': file_passed,
537
+ 'failed': file_failed,
538
+ 'run_count': 1})
532
539
 
533
540
  # Compute regression combined stats
534
541
  for reg in regressions.values():
@@ -572,7 +572,7 @@
572
572
  const skippedPct = Math.max(0, 100 - failedPct - passedPct);
573
573
 
574
574
  const runBadge = runCount > 1
575
- ? '<span class="run-count-badge" title="Ran ' + runCount + ' times">×' + runCount + '</span>'
575
+ ? '<span class="run-count-badge" title="Ran ' + runCount + ' times in this regression">×' + runCount + '</span>'
576
576
  : '';
577
577
 
578
578
  const metaText = runCount > 1
@@ -581,7 +581,7 @@
581
581
 
582
582
  // If multiple runs, navigate to history with search; otherwise go to single run
583
583
  const clickHandler = runCount > 1
584
- ? 'onclick="navigateToHistoryWithSearch(\'' + s.suite + '\')"'
584
+ ? 'onclick="navigateToHistoryWithSearch(\'' + s.suite + '\', \'' + reg.tag + '\')"'
585
585
  : 'onclick="goToRun(\'' + s.run_id + '\')"';
586
586
 
587
587
  return '<div class="suite-row" ' + clickHandler + '>' +
@@ -663,7 +663,7 @@
663
663
  if (runId) location.href = 'run.html?r=' + encodeURIComponent(runId) + '&p=' + encodeURIComponent(projectName);
664
664
  }
665
665
 
666
- function navigateToHistoryWithSearch(fileName) {
666
+ function navigateToHistoryWithSearch(fileName, tag) {
667
667
  // Find and click the Run History tab button
668
668
  const historyBtn = Array.from(document.querySelectorAll('.tab-btn')).find(function(btn) {
669
669
  return btn.textContent.trim() === 'Run History';
@@ -677,7 +677,9 @@
677
677
  setTimeout(function() {
678
678
  const searchInput = document.getElementById('historySearch');
679
679
  if (searchInput) {
680
- searchInput.value = fileName;
680
+ // Combine file name and tag for search
681
+ const searchValue = tag ? fileName + ' ' + tag : fileName;
682
+ searchInput.value = searchValue;
681
683
  filterHistory();
682
684
  // Scroll to the table
683
685
  searchInput.scrollIntoView({ behavior: 'smooth', block: 'start' });
@@ -901,7 +903,9 @@
901
903
  var bg = f.pass_rate >= 95 ? '#276749' : f.pass_rate >= 80 ? '#975a16' : '#9b2c2c';
902
904
  var bgLight = f.pass_rate >= 95 ? '#38a169' : f.pass_rate >= 80 ? '#d69e2e' : '#e53e3e';
903
905
  const hiddenClass = i >= limit ? ' treemap-cell-hidden' : '';
904
- const clickAttr = ' onclick="navigateToHistoryWithSearch(\'' + f.file_name + '\')" style="cursor:pointer;"';
906
+ // Strip .py extension for search to match display format
907
+ const searchName = f.file_name.replace(/\.py$/, '');
908
+ const clickAttr = ' onclick="navigateToHistoryWithSearch(\'' + searchName + '\')" style="cursor:pointer;"';
905
909
  return '<div class="treemap-cell' + hiddenClass + '" style="width:' + width + 'px;background:' + bgLight + ';" title="' + f.file_name + ': ' + f.pass_rate.toFixed(1) + '% pass rate (' + f.total_runs + ' runs) - Click to view all runs"' + clickAttr + '>' +
906
910
  '<div class="treemap-rate">' + f.pass_rate.toFixed(0) + '%</div>' +
907
911
  '<div class="treemap-name">' + f.file_name + '</div>' +
@@ -1033,7 +1037,7 @@
1033
1037
  '<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>' +
1034
1038
  '</div>' +
1035
1039
  '<div class="search-wrap">' +
1036
- '<input type="text" id="historySearch" class="search-input" placeholder="Search by test file name..." oninput="filterHistory()" />' +
1040
+ '<input type="text" id="historySearch" class="search-input" placeholder="Search by test file name or tag..." oninput="filterHistory()" />' +
1037
1041
  '</div>' +
1038
1042
  '<div class="section-body-flush">' +
1039
1043
  '<table class="hist-table" id="historyTable">' +
@@ -1111,9 +1115,13 @@
1111
1115
 
1112
1116
  rows.forEach(function(row) {
1113
1117
  const fileNameCell = row.querySelector('td:nth-child(3)');
1118
+ const tagCell = row.querySelector('td:nth-child(4)');
1114
1119
  if (fileNameCell) {
1115
1120
  const fileName = fileNameCell.textContent.toLowerCase();
1116
- if (fileName.includes(searchTerm)) {
1121
+ const tag = tagCell ? tagCell.textContent.toLowerCase() : '';
1122
+ // Match if search term is in file name OR tag
1123
+ const combinedText = fileName + ' ' + tag;
1124
+ if (combinedText.includes(searchTerm)) {
1117
1125
  row.style.display = '';
1118
1126
  visibleCount++;
1119
1127
  } else {
@@ -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.7.3',
12
+ version='3.7.4',
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.7.3
3
+ Version: 3.7.4
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