diff --git a/pom.xml b/pom.xml index 91efb8701..e657c824a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jenkins-ci.plugins plugin - 5.27 + 5.26 @@ -32,8 +32,8 @@ 999999-SNAPSHOT jenkinsci/${project.artifactId}-plugin - 2.504 - ${jenkins.baseline}.3 + 2.516 + 2.533 false false false 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/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..9d841417d --- /dev/null +++ b/src/main/java/hudson/tasks/junit/Widget.java @@ -0,0 +1,69 @@ +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/java/hudson/tasks/test/AbstractTestResultAction.java b/src/main/java/hudson/tasks/test/AbstractTestResultAction.java index 34207eb53..f10ab1472 100644 --- a/src/main/java/hudson/tasks/test/AbstractTestResultAction.java +++ b/src/main/java/hudson/tasks/test/AbstractTestResultAction.java @@ -51,7 +51,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import jenkins.management.Badge; import jenkins.model.RunAction2; +import jenkins.model.Tab; import jenkins.model.lazy.LazyBuildMixIn; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; @@ -81,7 +83,7 @@ * @author Kohsuke Kawaguchi */ @ExportedBean -public abstract class AbstractTestResultAction +public abstract class AbstractTestResultAction extends Tab implements HealthReportingAction, RunAction2 { private static final Logger LOGGER = Logger.getLogger(AbstractTestResultAction.class.getName()); @@ -99,7 +101,9 @@ public abstract class AbstractTestResultAction descriptions = new ConcurrentHashMap<>(); /** @since 1.545 */ - protected AbstractTestResultAction() {} + protected AbstractTestResultAction() { + super(null); + } /** * @deprecated Use the default constructor and just call {@link Run#addAction} to associate the build with the action. @@ -107,6 +111,7 @@ protected AbstractTestResultAction() {} */ @Deprecated protected AbstractTestResultAction(Run owner) { + super(owner); onAttached(owner); } @@ -117,12 +122,14 @@ protected AbstractTestResultAction(AbstractBuild owner) { @Override public void onAttached(Run r) { + this.object = r; this.run = r; this.owner = r instanceof AbstractBuild ? (AbstractBuild) r : null; } @Override public void onLoad(Run r) { + this.object = r; this.run = r; this.owner = r instanceof AbstractBuild ? (AbstractBuild) r : null; } @@ -180,6 +187,18 @@ public String getIconFileName() { return "symbol-flask-outline plugin-ionicons-api"; } + @Override + public Badge getBadge() { + if (getFailCount() == 0) { + return null; + } + + return new Badge( + String.valueOf(getFailCount()), + Messages.AbstractTestResultAction_Badge(getFailCount()), + Badge.Severity.DANGER); + } + @Override public HealthReport getBuildHealth() { final double scaleFactor = getHealthScaleFactor(); diff --git a/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly b/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly index 8b625b9fa..b8e4e977b 100644 --- a/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly +++ b/src/main/resources/hudson/tasks/junit/CaseResult/index.jelly @@ -23,89 +23,93 @@ THE SOFTWARE. --> - - - - - - - - -
-
-

- - ${it.displayName} - - - - ${it.className} - -

-
- + + + + + + + + + + + +
+
+ +

+ + ${it.displayName} + + + + ${it.className} + +

- - + - - - - -
+ + + + +
- - - + + 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. - - +
+ class="jenkins-!-margin-bottom-2 jenkins-!-margin-top-0" + style="display: flex; flex-direction: row; justify-content: space-between; align-items: center; height: auto; flex-wrap: wrap;" + > ${%Older} + class="jenkins-!-margin-right-2 jenkins-!-margin-bottom-1 jenkins-!-margin-top-1" style="height: fit-content">${%Older} ${%Newer} + class="jenkins-!-margin-right-2 jenkins-!-margin-bottom-1 jenkins-!-margin-top-1" style="height: fit-content">${%Newer}
@@ -94,14 +97,16 @@ 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}
- - + 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 + + + + + + + + + + + diff --git a/src/main/resources/hudson/tasks/test/AbstractTestResultAction/summary.jelly b/src/main/resources/hudson/tasks/test/AbstractTestResultAction/summary.jelly index f764c9d0b..2c9b50259 100644 --- a/src/main/resources/hudson/tasks/test/AbstractTestResultAction/summary.jelly +++ b/src/main/resources/hudson/tasks/test/AbstractTestResultAction/summary.jelly @@ -25,48 +25,49 @@ THE SOFTWARE. + - - - ${it.displayName} - - + + + ${it.displayName} + + - - - - -
    - - - - - + + + + +
      + + + + + - - - - - - + + + + + + -
    • - - - - - -
    • -
      -
    +
  • + + + + + +
  • +
    +
- - - - ${%Show all failed tests} ${">>>"} + + + + ${%Show all failed tests} ${">>>"} + -
- -
+
+
diff --git a/src/main/resources/hudson/tasks/test/AbstractTestResultAction/widget.jelly b/src/main/resources/hudson/tasks/test/AbstractTestResultAction/widget.jelly new file mode 100644 index 000000000..498551b06 --- /dev/null +++ b/src/main/resources/hudson/tasks/test/AbstractTestResultAction/widget.jelly @@ -0,0 +1,37 @@ + + + + + + + + + + +
${line}
+
+
+
+
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 - - + + - - + + - - - - + - + + + + - -