diff --git a/src/main/java/com/seleniumboot/reporting/HtmlReportGenerator.java b/src/main/java/com/seleniumboot/reporting/HtmlReportGenerator.java
index 13d3a6c..7376cf6 100644
--- a/src/main/java/com/seleniumboot/reporting/HtmlReportGenerator.java
+++ b/src/main/java/com/seleniumboot/reporting/HtmlReportGenerator.java
@@ -144,7 +144,7 @@ private static String buildScreenshotCell(JsonNode test) {
String base64 = Base64.getEncoder().encodeToString(bytes);
String src = "data:image/png;base64," + base64;
return "
";
+ + "onclick=\"openLightbox(this)\" title=\"Click to view full size\" />";
} catch (java.io.IOException e) {
return "load error";
}
@@ -1066,7 +1066,7 @@ private static String buildStepTimeline(JsonNode test) {
if (step.has("screenshotBase64")) {
String src = "data:image/png;base64," + step.get("screenshotBase64").asText();
thumbHtml = "
";
+ + "onclick=\"openLightbox(this)\" title=\"Click to view full size\" />";
}
sb.append("
")
diff --git a/src/main/resources/report/partials/lightbox.html b/src/main/resources/report/partials/lightbox.html
index 316a2c8..279988e 100644
--- a/src/main/resources/report/partials/lightbox.html
+++ b/src/main/resources/report/partials/lightbox.html
@@ -1,5 +1,8 @@
×
-
![Screenshot]()
+
+
![Screenshot]()
+
+
diff --git a/src/main/resources/report/report.css b/src/main/resources/report/report.css
index 6de8919..0c4122c 100644
--- a/src/main/resources/report/report.css
+++ b/src/main/resources/report/report.css
@@ -228,6 +228,12 @@
.lightbox img { max-width: 92vw; max-height: 92vh; border-radius: 6px; box-shadow: 0 8px 40px rgba(0,0,0,.6); }
.lightbox-close { position: fixed; top: 18px; right: 24px; color: #fff; font-size: 32px; cursor: pointer; line-height: 1; opacity: .8; }
.lightbox-close:hover { opacity: 1; }
+ .lightbox-nav { position: fixed; top: 50%; transform: translateY(-50%); background: rgba(255,255,255,.15); color: #fff; border: 0; border-radius: 50%; width: 44px; height: 44px; font-size: 20px; cursor: pointer; }
+ .lightbox-nav:hover:not(:disabled) { background: rgba(255,255,255,.3); }
+ .lightbox-nav:disabled { opacity: .25; cursor: default; }
+ .lightbox-prev { left: 20px; }
+ .lightbox-next { right: 20px; }
+ .lightbox-counter { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); color: #fff; font-size: 14px; background: rgba(0,0,0,.5); padding: 3px 12px; border-radius: 12px; }
/* ── Filter + search bar ── */
.filter-bar { display: flex; align-items: center; gap: 10px; padding: 14px 24px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
diff --git a/src/main/resources/report/report.js b/src/main/resources/report/report.js
index 5e08d00..d9334e1 100644
--- a/src/main/resources/report/report.js
+++ b/src/main/resources/report/report.js
@@ -6,18 +6,56 @@ function showTab(tabId, el) {
if (el) el.classList.add('active');
}
// ── Lightbox ──
-function openLightbox(src) {
- document.getElementById('lightbox-img').src = src;
+var lightboxImgs = [];
+var lightboxIdx = 0;
+// Screenshots of the same test: its row thumbnail plus the thumbnails in its detail row.
+function collectTestScreenshots(img) {
+ var row = img.closest('tr');
+ if (!row) return [img];
+ var testRow = row.classList.contains('detail-row') ? row.previousElementSibling : row;
+ var detailRow = testRow && testRow.nextElementSibling;
+ var rows = [testRow];
+ if (detailRow && detailRow.classList.contains('detail-row')) rows.push(detailRow);
+ var imgs = [];
+ rows.forEach(function(r) {
+ if (r) r.querySelectorAll('img.screenshot-thumb, img.step-thumb').forEach(function(i) { imgs.push(i); });
+ });
+ return imgs.indexOf(img) >= 0 ? imgs : [img];
+}
+function showLightbox() {
+ document.getElementById('lightbox-img').src = lightboxImgs[lightboxIdx].src;
+ var multi = lightboxImgs.length > 1;
+ document.getElementById('lightbox-counter').textContent = multi ? (lightboxIdx + 1) + ' / ' + lightboxImgs.length : '';
+ document.getElementById('lightbox-prev').style.display = multi ? '' : 'none';
+ document.getElementById('lightbox-next').style.display = multi ? '' : 'none';
+ document.getElementById('lightbox-prev').disabled = lightboxIdx === 0;
+ document.getElementById('lightbox-next').disabled = lightboxIdx === lightboxImgs.length - 1;
+}
+function openLightbox(img) {
+ lightboxImgs = collectTestScreenshots(img);
+ lightboxIdx = lightboxImgs.indexOf(img);
+ showLightbox();
document.getElementById('lightbox').classList.add('open');
document.body.style.overflow = 'hidden';
}
+function stepLightbox(delta, e) {
+ if (e) e.stopPropagation();
+ var next = lightboxIdx + delta;
+ if (next < 0 || next >= lightboxImgs.length) return;
+ lightboxIdx = next;
+ showLightbox();
+}
function closeLightbox() {
document.getElementById('lightbox').classList.remove('open');
document.getElementById('lightbox-img').src = '';
document.body.style.overflow = '';
+ lightboxImgs = [];
}
document.addEventListener('keydown', function(e) {
+ if (!document.getElementById('lightbox').classList.contains('open')) return;
if (e.key === 'Escape') closeLightbox();
+ else if (e.key === 'ArrowLeft') stepLightbox(-1);
+ else if (e.key === 'ArrowRight') stepLightbox(1);
});
// ── Dark mode ──
@@ -481,4 +519,4 @@ window.addEventListener('afterprint', function () {
}
printState = null;
-});
+});