test-reporting 3.6.1__tar.gz → 3.6.2__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.
- {test_reporting-3.6.1/test_reporting.egg-info → test_reporting-3.6.2}/PKG-INFO +1 -1
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/publisher.py +15 -5
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/templates/project.html +14 -2
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/templates/run.html +3 -1
- {test_reporting-3.6.1 → test_reporting-3.6.2}/setup.py +1 -1
- {test_reporting-3.6.1 → test_reporting-3.6.2/test_reporting.egg-info}/PKG-INFO +1 -1
- {test_reporting-3.6.1 → test_reporting-3.6.2}/LICENSE +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/README.md +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/__init__.py +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/classifier.py +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/cli.py +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/config.py +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/plugin.py +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/storage.py +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/reporting/templates/index.html +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/setup.cfg +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/test_reporting.egg-info/SOURCES.txt +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/test_reporting.egg-info/dependency_links.txt +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/test_reporting.egg-info/entry_points.txt +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/test_reporting.egg-info/requires.txt +0 -0
- {test_reporting-3.6.1 → test_reporting-3.6.2}/test_reporting.egg-info/top_level.txt +0 -0
|
@@ -493,8 +493,12 @@ class Publisher:
|
|
|
493
493
|
# Regression grouping
|
|
494
494
|
if tag not in regressions:
|
|
495
495
|
regressions[tag] = {'tag': tag, 'date': tag[:10], 'suites': [],
|
|
496
|
-
'total_tests': 0, 'passed': 0, 'failed': 0, 'pass_rate': 0
|
|
496
|
+
'total_tests': 0, 'passed': 0, 'failed': 0, 'pass_rate': 0,
|
|
497
|
+
'timestamp': ''}
|
|
497
498
|
reg = regressions[tag]
|
|
499
|
+
# Track the latest timestamp for this regression
|
|
500
|
+
if ts > reg.get('timestamp', ''):
|
|
501
|
+
reg['timestamp'] = ts
|
|
498
502
|
existing = next((s for s in reg['suites'] if s['suite'] == suite), None)
|
|
499
503
|
if existing:
|
|
500
504
|
if ts > existing.get('timestamp', ''):
|
|
@@ -525,8 +529,10 @@ class Publisher:
|
|
|
525
529
|
s['runs'] = sorted(s['runs'], key=lambda r: r['timestamp'], reverse=True)
|
|
526
530
|
s['runs'] = s['runs'][:self.config.DASHBOARD_MAX_RUNS_PER_SUITE]
|
|
527
531
|
|
|
528
|
-
# Sort regressions newest first
|
|
529
|
-
regressions = dict(sorted(regressions.items(),
|
|
532
|
+
# Sort regressions by timestamp (newest first), fallback to tag name
|
|
533
|
+
regressions = dict(sorted(regressions.items(),
|
|
534
|
+
key=lambda x: (x[1].get('timestamp', ''), x[0]),
|
|
535
|
+
reverse=True))
|
|
530
536
|
|
|
531
537
|
# Overall health from latest regression
|
|
532
538
|
last_reg = next(iter(regressions.values()), None) if regressions else None
|
|
@@ -745,7 +751,9 @@ class Publisher:
|
|
|
745
751
|
s3.put_object(Bucket=bucket, Key=dest_key, Body=f.read(),
|
|
746
752
|
ContentType='image/png')
|
|
747
753
|
print(f"[Reporting] ✓ Uploaded screenshot: {src.name}")
|
|
748
|
-
|
|
754
|
+
# Use full S3 URL so it works when dashboard is served from S3
|
|
755
|
+
s3_url = f"https://{bucket}.s3.{self.config.S3_REGION}.amazonaws.com/{dest_key}"
|
|
756
|
+
test['screenshot_path'] = s3_url
|
|
749
757
|
artifact_count += 1
|
|
750
758
|
else:
|
|
751
759
|
print(f"[Reporting] ✗ Screenshot not found: {src}")
|
|
@@ -761,7 +769,9 @@ class Publisher:
|
|
|
761
769
|
s3.put_object(Bucket=bucket, Key=dest_key, Body=f.read(),
|
|
762
770
|
ContentType='application/zip')
|
|
763
771
|
print(f"[Reporting] ✓ Uploaded trace: {src.name}")
|
|
764
|
-
|
|
772
|
+
# Use full S3 URL so it works when dashboard is served from S3
|
|
773
|
+
s3_url = f"https://{bucket}.s3.{self.config.S3_REGION}.amazonaws.com/{dest_key}"
|
|
774
|
+
test['trace_path'] = s3_url
|
|
765
775
|
artifact_count += 1
|
|
766
776
|
else:
|
|
767
777
|
print(f"[Reporting] ✗ Trace not found: {src}")
|
|
@@ -392,6 +392,14 @@
|
|
|
392
392
|
return new Date(iso).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', hour12: false });
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
+
function fmtDateTime(iso) {
|
|
396
|
+
if (!iso) return '-';
|
|
397
|
+
const date = new Date(iso);
|
|
398
|
+
const dateStr = date.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
|
|
399
|
+
const timeStr = date.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', hour12: false });
|
|
400
|
+
return dateStr + ' ' + timeStr;
|
|
401
|
+
}
|
|
402
|
+
|
|
395
403
|
function fmtDur(s) {
|
|
396
404
|
if (!s || s === 0) return '-';
|
|
397
405
|
if (s >= 60) return Math.floor(s / 60) + 'm ' + Math.floor(s % 60) + 's';
|
|
@@ -553,10 +561,12 @@
|
|
|
553
561
|
}).join('');
|
|
554
562
|
|
|
555
563
|
const isOpen = i === 0;
|
|
564
|
+
const regDateTime = reg.timestamp ? fmtDateTime(reg.timestamp) : '';
|
|
565
|
+
const regTitle = regDateTime ? reg.tag + ' · ' + regDateTime : reg.tag;
|
|
556
566
|
return '<div class="regression">' +
|
|
557
567
|
'<div class="reg-head" onclick="toggleReg(this)">' +
|
|
558
568
|
'<div>' +
|
|
559
|
-
'<div class="reg-title">' +
|
|
569
|
+
'<div class="reg-title">' + regTitle + '</div>' +
|
|
560
570
|
'<div class="reg-sub">' + reg.suites.length + ' test ' + plural(reg.suites.length, 'file') + ' · ' + reg.total_tests + ' tests</div>' +
|
|
561
571
|
'</div>' +
|
|
562
572
|
'<div class="reg-right">' +
|
|
@@ -1207,7 +1217,9 @@
|
|
|
1207
1217
|
}
|
|
1208
1218
|
|
|
1209
1219
|
document.getElementById('pageTitle').textContent = proj.name;
|
|
1210
|
-
document.getElementById('lastRun')
|
|
1220
|
+
const lastRunEl = document.getElementById('lastRun');
|
|
1221
|
+
lastRunEl.textContent = 'Last run ' + relTime(proj.last_run);
|
|
1222
|
+
lastRunEl.title = 'All times shown in your local timezone';
|
|
1211
1223
|
document.title = proj.name + ' - Test Dashboard';
|
|
1212
1224
|
|
|
1213
1225
|
const analytics = proj.analytics || {};
|
|
@@ -413,7 +413,9 @@
|
|
|
413
413
|
document.title = (run.suite_name || 'Run') + ' - Test Dashboard';
|
|
414
414
|
document.getElementById('pageTitle').textContent =
|
|
415
415
|
(run.suite_name || 'Run') + ' · ' + (run.project_name || '');
|
|
416
|
-
document.getElementById('runTime')
|
|
416
|
+
var runTimeEl = document.getElementById('runTime');
|
|
417
|
+
runTimeEl.textContent = fmtDate(run.timestamp);
|
|
418
|
+
runTimeEl.title = 'Time shown in your local timezone';
|
|
417
419
|
|
|
418
420
|
var backHref = projectName
|
|
419
421
|
? 'project.html?p=' + encodeURIComponent(projectName)
|
|
@@ -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.
|
|
12
|
+
version='3.6.2',
|
|
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",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|