${passCount} passing, ${skipCount} skipped, ${totalCount} ran
From 97530cf7a2c838e234254cb3a2adddec7f1a8091 Mon Sep 17 00:00:00 2001
From: Jan Faracik <43062514+janfaracik@users.noreply.github.com>
Date: Wed, 22 Oct 2025 16:49:28 +0100
Subject: [PATCH 07/12] Improve card + i18n
---
.../hudson/tasks/junit/TestResultAction.java | 4 ++
src/main/java/hudson/tasks/junit/Widget.java | 64 +++++++++++++++++++
.../hudson/tasks/junit/Messages.properties | 8 +++
.../AbstractTestResultAction/widget.jelly | 45 +++----------
.../widget.properties | 1 -
5 files changed, 84 insertions(+), 38 deletions(-)
create mode 100644 src/main/java/hudson/tasks/junit/Widget.java
delete mode 100644 src/main/resources/hudson/tasks/test/AbstractTestResultAction/widget.properties
diff --git a/src/main/java/hudson/tasks/junit/TestResultAction.java b/src/main/java/hudson/tasks/junit/TestResultAction.java
index 3c75bb532..1dc5990c4 100644
--- a/src/main/java/hudson/tasks/junit/TestResultAction.java
+++ b/src/main/java/hudson/tasks/junit/TestResultAction.java
@@ -415,6 +415,10 @@ public Object readResolve() {
return this;
}
+ public Widget getWidget() {
+ return new Widget(getResult());
+ }
+
private static final Logger logger = Logger.getLogger(TestResultAction.class.getName());
static final XStream XSTREAM = new XStream2();
diff --git a/src/main/java/hudson/tasks/junit/Widget.java b/src/main/java/hudson/tasks/junit/Widget.java
new file mode 100644
index 000000000..960ed04bc
--- /dev/null
+++ b/src/main/java/hudson/tasks/junit/Widget.java
@@ -0,0 +1,64 @@
+package hudson.tasks.junit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Widget {
+
+ private final String symbol;
+ private final String symbolClass;
+ private final List
lines = new ArrayList<>();
+
+ public Widget(TestResult result) {
+ int failCount = result.getFailCount();
+ boolean isFailed = failCount > 0;
+ int totalCount = result.getTotalCount();
+
+ this.symbol = isFailed ? "symbol-close-circle-outline plugin-ionicons-api" : "symbol-checkmark-done-outline plugin-ionicons-api";
+ this.symbolClass = isFailed ? "jenkins-!-error-color" : "jenkins-!-success-color";
+
+ List counts = new ArrayList<>();
+
+ if (isFailed) {
+ lines.add(Messages.Widget_Failed(failCount));
+ counts.add(Messages.Widget_Passed(result.getPassCount()));
+
+ long regressions = result.getSuites().stream().flatMap(e -> e.getCases().stream()).filter(e -> {
+ var previousResult = e.getPreviousResult();
+ if (previousResult == null) {
+ return false;
+ }
+ return e.isPassed();
+ }).count();
+
+ if (regressions > 0) {
+ lines.add(Messages.Widget_Regression(regressions));
+ }
+
+ } else {
+ lines.add(Messages.Widget_AllTestsPassing());
+ }
+
+ if (result.getSkipCount() > 0) {
+ counts.add(Messages.Widget_Skipped(result.getSkipCount()));
+ }
+
+ counts.add(Messages.Widget_Total(totalCount));
+
+ lines.add(String.join(", ", counts));
+
+ lines.add(Messages.Widget_Took(result.getDurationString()));
+ }
+
+ public String getSymbol() {
+ return symbol;
+ }
+
+ public String getSymbolClass() {
+ return symbolClass;
+ }
+
+ public List getLines() {
+ return lines;
+ }
+}
diff --git a/src/main/resources/hudson/tasks/junit/Messages.properties b/src/main/resources/hudson/tasks/junit/Messages.properties
index 8e22cd40a..da75911f2 100644
--- a/src/main/resources/hudson/tasks/junit/Messages.properties
+++ b/src/main/resources/hudson/tasks/junit/Messages.properties
@@ -45,3 +45,11 @@ CaseResult.Status.Regression=Regression
StdioRetention.All.DisplayName=All tests
StdioRetention.Failed.DisplayName=Failed tests only
StdioRetention.None.DisplayName=None
+
+Widget.AllTestsPassing=All tests are passing!
+Widget.Failed={0} {0,choice,1#test|1
-
-
-
-
-
-
-
-
-
- ${failCount} failing ${failCount eq 1 ? 'test' : 'tests'}
-
-
- ${passCount} passing, ${skipCount} skipped, ${totalCount} ran
-
-
-
- ${%took(duration)}
-
-
-
-
-
-
-
- All tests are passing!
-
-
- ${skipCount} skipped, ${totalCount} passed
-
-
-
- ${%took(duration)}
-
-
-
+
+
+
+
+
+ ${line}
+
+
diff --git a/src/main/resources/hudson/tasks/test/AbstractTestResultAction/widget.properties b/src/main/resources/hudson/tasks/test/AbstractTestResultAction/widget.properties
deleted file mode 100644
index 38558cef1..000000000
--- a/src/main/resources/hudson/tasks/test/AbstractTestResultAction/widget.properties
+++ /dev/null
@@ -1 +0,0 @@
-took=Took {0}
From 179426039dddd9360ace28e3f370f9e868d58807 Mon Sep 17 00:00:00 2001
From: Jan Faracik <43062514+janfaracik@users.noreply.github.com>
Date: Wed, 22 Oct 2025 16:49:37 +0100
Subject: [PATCH 08/12] Update Widget.java
---
src/main/java/hudson/tasks/junit/Widget.java | 21 ++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/src/main/java/hudson/tasks/junit/Widget.java b/src/main/java/hudson/tasks/junit/Widget.java
index 960ed04bc..9d841417d 100644
--- a/src/main/java/hudson/tasks/junit/Widget.java
+++ b/src/main/java/hudson/tasks/junit/Widget.java
@@ -14,7 +14,9 @@ public Widget(TestResult result) {
boolean isFailed = failCount > 0;
int totalCount = result.getTotalCount();
- this.symbol = isFailed ? "symbol-close-circle-outline plugin-ionicons-api" : "symbol-checkmark-done-outline plugin-ionicons-api";
+ this.symbol = isFailed
+ ? "symbol-close-circle-outline plugin-ionicons-api"
+ : "symbol-checkmark-done-outline plugin-ionicons-api";
this.symbolClass = isFailed ? "jenkins-!-error-color" : "jenkins-!-success-color";
List counts = new ArrayList<>();
@@ -23,13 +25,16 @@ public Widget(TestResult result) {
lines.add(Messages.Widget_Failed(failCount));
counts.add(Messages.Widget_Passed(result.getPassCount()));
- long regressions = result.getSuites().stream().flatMap(e -> e.getCases().stream()).filter(e -> {
- var previousResult = e.getPreviousResult();
- if (previousResult == null) {
- return false;
- }
- return e.isPassed();
- }).count();
+ long regressions = result.getSuites().stream()
+ .flatMap(e -> e.getCases().stream())
+ .filter(e -> {
+ var previousResult = e.getPreviousResult();
+ if (previousResult == null) {
+ return false;
+ }
+ return e.isPassed();
+ })
+ .count();
if (regressions > 0) {
lines.add(Messages.Widget_Regression(regressions));
From 07a0a2d668f8050326100c94f218bff97f1accd8 Mon Sep 17 00:00:00 2001
From: Jan Faracik <43062514+janfaracik@users.noreply.github.com>
Date: Wed, 22 Oct 2025 17:13:12 +0100
Subject: [PATCH 09/12] Add run sub page for individual tests
---
.../java/hudson/tasks/junit/CaseResult.java | 6 +-
.../hudson/tasks/junit/CaseResult/index.jelly | 156 +++++++++---------
.../hudson/tasks/test/TestResult/index.jelly | 6 +
src/main/webapp/styles.css | 15 +-
4 files changed, 89 insertions(+), 94 deletions(-)
diff --git a/src/main/java/hudson/tasks/junit/CaseResult.java b/src/main/java/hudson/tasks/junit/CaseResult.java
index d87d6b355..39544099c 100644
--- a/src/main/java/hudson/tasks/junit/CaseResult.java
+++ b/src/main/java/hudson/tasks/junit/CaseResult.java
@@ -1099,9 +1099,9 @@ public boolean isRegression() {
@Restricted(NoExternalUse.class)
public String getIconFileName() {
return switch (getStatus()) {
- case PASSED -> "symbol-checkmark-outline plugin-ionicons-api";
- case SKIPPED -> "symbol-play-skip-forward-outline plugin-ionicons-api";
- default -> "symbol-close-outline plugin-ionicons-api";
+ case PASSED -> "symbol-status-blue";
+ case SKIPPED -> "symbol-status-skipped plugin-junit";
+ default -> "symbol-status-red";
};
}
}
diff --git a/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly b/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly
index 408598d61..b8e4e977b 100644
--- a/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly
+++ b/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly
@@ -23,91 +23,93 @@ THE SOFTWARE.
-->
-
-
-
-
-
-
-
-
-
-
-
-
- ${it.displayName}
-
-
-
- ${it.className}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${it.displayName}
+
+
+
+ ${it.className}
+
+
-
-
-
- ${it.status.message}
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
diff --git a/src/main/resources/hudson/tasks/test/TestResult/index.jelly b/src/main/resources/hudson/tasks/test/TestResult/index.jelly
index 633661c05..cf135e24a 100644
--- a/src/main/resources/hudson/tasks/test/TestResult/index.jelly
+++ b/src/main/resources/hudson/tasks/test/TestResult/index.jelly
@@ -91,6 +91,12 @@ THE SOFTWARE.
${%took(it.durationString)}
+
+
+
+
diff --git a/src/main/webapp/styles.css b/src/main/webapp/styles.css
index aee7515b1..ce7aa3a98 100644
--- a/src/main/webapp/styles.css
+++ b/src/main/webapp/styles.css
@@ -1,17 +1,4 @@
-/* Details and pills */
-.jp-details {
- display: flex;
- align-items: center;
- gap: 0.75rem;
- margin-bottom: 0.875rem;
- margin-top: -0.25rem;
- flex-wrap: wrap;
-
- @media (width <= 800px) {
- margin-block: 0.75rem 1rem;
- }
-}
-
+/* Pills */
.jp-pills {
display: flex;
gap: var(--jenkins-border-width);
From d13e64422dfd832a1409f60f4382d3f08b961107 Mon Sep 17 00:00:00 2001
From: Jan Faracik <43062514+janfaracik@users.noreply.github.com>
Date: Wed, 22 Oct 2025 17:17:06 +0100
Subject: [PATCH 10/12] Update history to align with run subpage
---
.../hudson/tasks/junit/History/index.jelly | 58 ++++++++++---------
1 file changed, 31 insertions(+), 27 deletions(-)
diff --git a/src/main/resources/hudson/tasks/junit/History/index.jelly b/src/main/resources/hudson/tasks/junit/History/index.jelly
index 8d29e7c1e..bd3202f1e 100644
--- a/src/main/resources/hudson/tasks/junit/History/index.jelly
+++ b/src/main/resources/hudson/tasks/junit/History/index.jelly
@@ -24,8 +24,12 @@ THE SOFTWARE.
-
-
+
+
+
+
+
+
@@ -40,31 +44,30 @@ THE SOFTWARE.
-
-
+
+
+
History
-
+
@@ -110,9 +115,9 @@ THE SOFTWARE.
Distribution
-
+
@@ -121,13 +126,13 @@ THE SOFTWARE.
- ${%Older}
+ ${%Older}
- ${%Newer}
+ ${%Newer}
@@ -169,16 +174,15 @@ THE SOFTWARE.
- ${%Older}
+ ${%Older}
- ${%Newer}
+ ${%Newer}
-
-
+
From 08b26f1c301bdb72935d7409c1625b74bb25b963 Mon Sep 17 00:00:00 2001
From: Jan Faracik <43062514+janfaracik@users.noreply.github.com>
Date: Fri, 24 Oct 2025 11:07:24 +0100
Subject: [PATCH 11/12] I18n last string
---
.../java/hudson/tasks/test/AbstractTestResultAction.java | 5 ++++-
src/main/resources/hudson/tasks/test/Messages.properties | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/main/java/hudson/tasks/test/AbstractTestResultAction.java b/src/main/java/hudson/tasks/test/AbstractTestResultAction.java
index e2c21ee67..f10ab1472 100644
--- a/src/main/java/hudson/tasks/test/AbstractTestResultAction.java
+++ b/src/main/java/hudson/tasks/test/AbstractTestResultAction.java
@@ -193,7 +193,10 @@ public Badge getBadge() {
return null;
}
- return new Badge(String.valueOf(getFailCount()), getFailCount() + " test failure", Badge.Severity.DANGER);
+ return new Badge(
+ String.valueOf(getFailCount()),
+ Messages.AbstractTestResultAction_Badge(getFailCount()),
+ Badge.Severity.DANGER);
}
@Override
diff --git a/src/main/resources/hudson/tasks/test/Messages.properties b/src/main/resources/hudson/tasks/test/Messages.properties
index 9c697cc4c..f6ffe87eb 100644
--- a/src/main/resources/hudson/tasks/test/Messages.properties
+++ b/src/main/resources/hudson/tasks/test/Messages.properties
@@ -28,6 +28,7 @@ AbstractTestResultAction.TestsDescription={0}: {1} {1,choice,0#tests|1#test|1