From 670d70aac4e4a0f4572277143ed1528e34b4ac96 Mon Sep 17 00:00:00 2001 From: Jochen Delabie Date: Thu, 16 Jul 2026 16:25:27 +0200 Subject: [PATCH 1/3] Show inline session media (thumbnail + expandable) on the build page The build summary and the TestingBot embed page listed each session as a plain text link. Each session now shows a preview thumbnail and expands in place (native details/summary) to the full mini view (video, screenshots, logs). TestingBotBuildObject gains a thumbUrl derived from the session's first available thumbnail at build completion (Strings only, JEP-200-safe; no extra network I/O since the test details are already fetched). The embedded iframe uses loading=lazy so collapsed rows stay lightweight and the media loads only when a session is expanded. Sessions without assets degrade to just the expand control. --- README.md | 2 + .../testingbot/TestingBotBuildObject.java | 23 +++++- .../TestingBotBuildSummary/summary.jelly | 76 +++++++++---------- .../TestingBotTestEmbed/index.jelly | 73 ++++++++---------- 4 files changed, 91 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index a95f838..c3db685 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ An example on how to do this: `((RemoteWebDriver) driver).getSessionId().toStrin A full example that you can use is available on our GitHub [Jenkins-Demo](https://github.com/testingbot/Jenkins-Demo) page. +On the build page, each TestingBot session is shown with a preview thumbnail and expands in place to the full session media (video screencast, screenshots and logs) — no need to leave Jenkins. Collapsed sessions stay lightweight; the media only loads when a session is expanded. + ## Pipeline The plugin offers pipeline support, which can be used with a Jenkinsfile. diff --git a/src/main/java/testingbot/TestingBotBuildObject.java b/src/main/java/testingbot/TestingBotBuildObject.java index 100c02f..22cf205 100644 --- a/src/main/java/testingbot/TestingBotBuildObject.java +++ b/src/main/java/testingbot/TestingBotBuildObject.java @@ -3,6 +3,7 @@ import com.testingbot.models.TestingbotTest; import java.io.Serializable; +import java.util.List; public class TestingBotBuildObject implements Serializable { private static final long serialVersionUID = 1L; @@ -12,6 +13,7 @@ public class TestingBotBuildObject implements Serializable { private final boolean isPassed; private String authHash; private String environmentName; + private String thumbUrl; public TestingBotBuildObject(String sessionId, String className, String testName, boolean isPassed, String authHash, TestingbotTest test) { this.sessionId = sessionId; @@ -19,9 +21,24 @@ public TestingBotBuildObject(String sessionId, String className, String testName this.testName = testName; this.isPassed = isPassed; this.authHash = authHash; - // TestingbotTest is only used here to derive the environment label; it is not stored (it is not - // marshalable under the JEP-200 class filter, and nothing reads it afterwards). - this.environmentName = test == null ? "" : test.getBrowser() + " | " + test.getOs(); + // TestingbotTest is only used here to derive display fields; it is not stored (it is not + // marshalable under the JEP-200 class filter, and nothing reads it afterwards). Only the derived + // Strings are kept, which marshal cleanly. + if (test == null) { + this.environmentName = ""; + this.thumbUrl = ""; + } else { + this.environmentName = test.getBrowser() + " | " + test.getOs(); + List thumbs = test.getThumbs(); + this.thumbUrl = (test.isAssetsAvailable() && thumbs != null && !thumbs.isEmpty()) ? thumbs.get(0) : ""; + } + } + + /** + * @return a preview thumbnail URL for the session, or an empty string when no assets are available. + */ + public String getThumbUrl() { + return thumbUrl; } /** diff --git a/src/main/resources/testingbot/TestingBotBuildSummary/summary.jelly b/src/main/resources/testingbot/TestingBotBuildSummary/summary.jelly index c0acd47..1b15eeb 100644 --- a/src/main/resources/testingbot/TestingBotBuildSummary/summary.jelly +++ b/src/main/resources/testingbot/TestingBotBuildSummary/summary.jelly @@ -1,43 +1,39 @@ - TestingBot results -
- - - - - - - - - - - - - - - - - -
TestNameEnvironmentPassed?
- ${cs.testName} - - ${cs.environmentName} - - - - - - + TestingBot results +
+ +
+ + + + + ${cs.testName} + ${cs.environmentName} + + + + - - - - - - - - -
-
-
\ No newline at end of file + + + + + + + + +
+ View on TestingBot +
+ + +
+
+ + + + diff --git a/src/main/resources/testingbot/TestingBotTestEmbed/index.jelly b/src/main/resources/testingbot/TestingBotTestEmbed/index.jelly index 233bd9c..7c482af 100644 --- a/src/main/resources/testingbot/TestingBotTestEmbed/index.jelly +++ b/src/main/resources/testingbot/TestingBotTestEmbed/index.jelly @@ -1,49 +1,42 @@ - +

TestingBot results

- - - - - - - - - - - - - - - - - -
TestNameEnvironmentPassed?
- ${cs.testName} - - ${cs.environmentName} - - - - - - - - - - - - - - - -
- + +
+ + + + + ${cs.testName} + ${cs.environmentName} + + + + + + + + + + + + + +
+ View on TestingBot +
+ +
+
+
+
-
\ No newline at end of file + From 6141d4d09ec2c5261cd225b8e534b169b584c8f9 Mon Sep 17 00:00:00 2001 From: Jochen Delabie Date: Thu, 16 Jul 2026 17:46:55 +0200 Subject: [PATCH 2/3] Address review on #31: escape summary PCDATA, label status icons, soften README - Add the escape-by-default directive to summary.jelly so dynamic values (cs.testName, cs.environmentName) are HTML-escaped, matching index.jelly and preventing markup in a session/test name from injecting into the build page. - Give the pass/fail status SVGs an accessible name (role=img + aria-label Passed/Failed) in both summary.jelly and the embed index.jelly. - Soften the README wording from "only loads when expanded" to "loads lazily", since loading=lazy defers but does not strictly guarantee load-on- expand across browsers. --- README.md | 2 +- .../testingbot/TestingBotBuildSummary/summary.jelly | 5 +++-- .../resources/testingbot/TestingBotTestEmbed/index.jelly | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c3db685..d9f4729 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ An example on how to do this: `((RemoteWebDriver) driver).getSessionId().toStrin A full example that you can use is available on our GitHub [Jenkins-Demo](https://github.com/testingbot/Jenkins-Demo) page. -On the build page, each TestingBot session is shown with a preview thumbnail and expands in place to the full session media (video screencast, screenshots and logs) — no need to leave Jenkins. Collapsed sessions stay lightweight; the media only loads when a session is expanded. +On the build page, each TestingBot session is shown with a preview thumbnail and expands in place to the full session media (video screencast, screenshots and logs) — no need to leave Jenkins. The embedded media loads lazily, so collapsed sessions stay lightweight. ## Pipeline The plugin offers pipeline support, which can be used with a Jenkinsfile. diff --git a/src/main/resources/testingbot/TestingBotBuildSummary/summary.jelly b/src/main/resources/testingbot/TestingBotBuildSummary/summary.jelly index 1b15eeb..d250db3 100644 --- a/src/main/resources/testingbot/TestingBotBuildSummary/summary.jelly +++ b/src/main/resources/testingbot/TestingBotBuildSummary/summary.jelly @@ -1,3 +1,4 @@ + TestingBot results @@ -13,12 +14,12 @@ ${cs.environmentName} - + - + diff --git a/src/main/resources/testingbot/TestingBotTestEmbed/index.jelly b/src/main/resources/testingbot/TestingBotTestEmbed/index.jelly index 7c482af..4ae9ebc 100644 --- a/src/main/resources/testingbot/TestingBotTestEmbed/index.jelly +++ b/src/main/resources/testingbot/TestingBotTestEmbed/index.jelly @@ -17,12 +17,12 @@ ${cs.environmentName} - + - + From a824afa3f73da2080a381aa5869f9e06a7c76e0c Mon Sep 17 00:00:00 2001 From: Jochen Delabie Date: Thu, 16 Jul 2026 21:05:25 +0200 Subject: [PATCH 3/3] Null-safe getThumbUrl + accurate media wording (review on #31) - TestingBotBuildObject.getThumbUrl() returns "" when thumbUrl is null, so build records persisted before the field existed (deserialized as null) don't render a broken thumbnail img. - README now states the build page shows each JUnit test's session (the first one when a test records several), matching TestingBotBuildSummary which keys on sessionIds.get(0) per case. --- README.md | 2 +- src/main/java/testingbot/TestingBotBuildObject.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d1d2e4f..77b567a 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ An example on how to do this: `((RemoteWebDriver) driver).getSessionId().toStrin A full example that you can use is available on our GitHub [Jenkins-Demo](https://github.com/testingbot/Jenkins-Demo) page. -On the build page, each TestingBot session is shown with a preview thumbnail and expands in place to the full session media (video screencast, screenshots and logs) — no need to leave Jenkins. The embedded media loads lazily, so collapsed sessions stay lightweight. +On the build page, each JUnit test that used TestingBot is shown with a preview thumbnail of its session (the first one, if a test records several) and expands in place to the full session media (video screencast, screenshots and logs) — no need to leave Jenkins. The embedded media loads lazily, so collapsed sessions stay lightweight. ## Embedded TestingBot Build report diff --git a/src/main/java/testingbot/TestingBotBuildObject.java b/src/main/java/testingbot/TestingBotBuildObject.java index 22cf205..d23ce6c 100644 --- a/src/main/java/testingbot/TestingBotBuildObject.java +++ b/src/main/java/testingbot/TestingBotBuildObject.java @@ -38,7 +38,8 @@ public TestingBotBuildObject(String sessionId, String className, String testName * @return a preview thumbnail URL for the session, or an empty string when no assets are available. */ public String getThumbUrl() { - return thumbUrl; + // Null-safe for build.xml records persisted before this field existed (deserialized as null). + return thumbUrl == null ? "" : thumbUrl; } /**