Skip to content

Commit

Permalink
Upgrade trends and detail views to Bootstrap 5 (#272)
Browse files Browse the repository at this point in the history
Co-authored-by: Tim Jacomb <[email protected]>
Co-authored-by: Tim Jacomb <[email protected]>
  • Loading branch information
3 people authored May 2, 2022
1 parent 86b06fd commit 433a2d8
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 158 deletions.
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>echarts-api</artifactId>
<version>5.3.2-1</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
Expand Down Expand Up @@ -74,7 +75,8 @@
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>bootstrap4-api</artifactId>
<artifactId>bootstrap5-api</artifactId>
<version>5.1.3-6</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
Expand Down
41 changes: 22 additions & 19 deletions src/main/java/hudson/tasks/junit/History.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,24 @@
*/
package hudson.tasks.junit;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import edu.hm.hafner.echarts.ChartModelConfiguration;
import edu.hm.hafner.echarts.JacksonFacade;
import edu.hm.hafner.echarts.LinesChartModel;

import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.bind.JavaScriptMethod;
import hudson.tasks.test.TestObject;
import hudson.tasks.test.TestObjectIterable;
import hudson.tasks.test.TestResultDurationChart;
import hudson.tasks.test.TestResultTrendChart;
import hudson.util.RunList;
import io.jenkins.plugins.junit.storage.TestResultImpl;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.bind.JavaScriptMethod;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import io.jenkins.plugins.junit.storage.TestResultImpl;

/**
* History of {@link hudson.tasks.test.TestObject} over time.
Expand All @@ -48,6 +50,7 @@
@Restricted(NoExternalUse.class)
public class History {
private static final JacksonFacade JACKSON_FACADE = new JacksonFacade();
private static final String EMPTY_CONFIGURATION = "{}";
private final TestObject testObject;

public History(TestObject testObject) {
Expand All @@ -73,33 +76,37 @@ public boolean historyAvailable() {

@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
public String getTestResultTrend() {
return JACKSON_FACADE.toJson(createTestResultTrend());
public String getTestResultTrend(String configuration) {
return JACKSON_FACADE.toJson(createTestResultTrend(ChartModelConfiguration.fromJson(configuration)));
}

private LinesChartModel createTestResultTrend() {
private LinesChartModel createTestResultTrend(ChartModelConfiguration chartModelConfiguration) {
TestResultImpl pluggableStorage = getPluggableStorage();
if (pluggableStorage != null) {
return new TestResultTrendChart().create(pluggableStorage.getTrendTestResultSummary());
}

return new TestResultTrendChart().createFromTestObject(createBuildHistory(testObject), new ChartModelConfiguration());
return new TestResultTrendChart().createFromTestObject(createBuildHistory(testObject), chartModelConfiguration);
}

@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
public String getTestDurationTrend() {
return JACKSON_FACADE.toJson(createTestDurationResultTrend());
public String getTestDurationTrend(String configuration) {
return JACKSON_FACADE.toJson(createTestDurationResultTrend(ChartModelConfiguration.fromJson(configuration)));
}

private LinesChartModel createTestDurationResultTrend() {
private LinesChartModel createTestDurationResultTrend(ChartModelConfiguration chartModelConfiguration) {
TestResultImpl pluggableStorage = getPluggableStorage();

if (pluggableStorage != null) {
return new TestResultDurationChart().create(pluggableStorage.getTestDurationResultSummary());
}

return new TestResultDurationChart().create(createBuildHistory(testObject), new ChartModelConfiguration());
return new TestResultDurationChart().create(createBuildHistory(testObject), chartModelConfiguration);
}

private TestObjectIterable createBuildHistory(final TestObject testObject) {
return new TestObjectIterable(testObject);
}

private TestResultImpl getPluggableStorage() {
Expand Down Expand Up @@ -171,10 +178,6 @@ private List<HistoryTestResultSummary> getHistoryFromFileStorage() {
.collect(Collectors.toList());
}

private TestObjectIterable createBuildHistory(TestObject testObject) {
return new TestObjectIterable(testObject);
}

@SuppressWarnings("unused") // Called by jelly view
public static int asInt(String s, int defaultValue) {
if (s == null) return defaultValue;
Expand Down
10 changes: 4 additions & 6 deletions src/main/java/hudson/tasks/test/TestResultDurationChart.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import static hudson.tasks.test.TestDurationTrendSeriesBuilder.SECONDS;

public class TestResultDurationChart {

public LinesChartModel create(List<TestDurationResultSummary> results) {
LinesDataSet dataset = new LinesDataSet();
results.forEach(result -> dataset.add(result.getDisplayName(), result.toMap(), result.getBuildNumber()));

return getLinesChartModel(dataset);
}

Expand All @@ -28,15 +28,13 @@ public LinesChartModel create(final Iterable results,
}

private LinesChartModel getLinesChartModel(LinesDataSet dataSet) {
LinesChartModel model = new LinesChartModel();
model.setDomainAxisLabels(dataSet.getDomainAxisLabels());
model.setBuildNumbers(dataSet.getBuildNumbers());
LinesChartModel model = new LinesChartModel(dataSet);

LineSeries duration = new LineSeries(SECONDS, Palette.GREEN.getNormal(),
LineSeries.StackedMode.STACKED, LineSeries.FilledMode.FILLED);
duration.addAll(dataSet.getSeries(SECONDS));
model.addSeries(duration);

return model;
}
}
69 changes: 41 additions & 28 deletions src/main/java/hudson/tasks/test/TestResultProjectAction.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/*
* The MIT License
*
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -23,29 +23,32 @@
*/
package hudson.tasks.test;

import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import edu.hm.hafner.echarts.ChartModelConfiguration;
import edu.hm.hafner.echarts.JacksonFacade;
import edu.hm.hafner.echarts.LinesChartModel;
import edu.umd.cs.findbugs.annotations.CheckForNull;

import org.kohsuke.stapler.Ancestor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.bind.JavaScriptMethod;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.Job;
import hudson.model.Run;
import hudson.tasks.junit.JUnitResultArchiver;

import io.jenkins.plugins.echarts.AsyncConfigurableTrendChart;
import io.jenkins.plugins.echarts.AsyncTrendChart;
import io.jenkins.plugins.junit.storage.FileJunitTestResultStorage;
import io.jenkins.plugins.junit.storage.TestResultImpl;
import io.jenkins.plugins.junit.storage.JunitTestResultStorage;
import io.jenkins.plugins.echarts.AsyncTrendChart;
import org.kohsuke.stapler.Ancestor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import org.kohsuke.stapler.bind.JavaScriptMethod;
import io.jenkins.plugins.junit.storage.TestResultImpl;

/**
* Project action object from test reporter, such as {@link JUnitResultArchiver},
Expand All @@ -56,7 +59,7 @@
*
* @author Kohsuke Kawaguchi
*/
public class TestResultProjectAction implements Action, AsyncTrendChart {
public class TestResultProjectAction implements Action, AsyncTrendChart, AsyncConfigurableTrendChart {
/**
* Project that owns this action.
* @since 1.2-beta-1
Expand All @@ -69,13 +72,13 @@ public class TestResultProjectAction implements Action, AsyncTrendChart {
/**
* @since 1.2-beta-1
*/
public TestResultProjectAction(Job<?,?> job) {
public TestResultProjectAction(final Job<?,?> job) {
this.job = job;
project = job instanceof AbstractProject ? (AbstractProject) job : null;
}

@Deprecated
public TestResultProjectAction(AbstractProject<?,?> project) {
public TestResultProjectAction(final AbstractProject<?,?> project) {
this((Job) project);
}

Expand Down Expand Up @@ -114,7 +117,12 @@ public AbstractTestResultAction getLastTestResultAction() {
return null;
}

@Deprecated
protected LinesChartModel createChartModel() {
return createChartModel(new ChartModelConfiguration());
}

private LinesChartModel createChartModel(final ChartModelConfiguration configuration) {
Run<?, ?> lastCompletedBuild = job.getLastCompletedBuild();

JunitTestResultStorage storage = JunitTestResultStorage.find();
Expand All @@ -127,11 +135,11 @@ protected LinesChartModel createChartModel() {
if (buildHistory == null) {
return new LinesChartModel();
}
return new TestResultTrendChart().create(buildHistory, new ChartModelConfiguration());
return new TestResultTrendChart().create(buildHistory, configuration);
}

@CheckForNull
private TestResultActionIterable createBuildHistory(Run<?, ?> lastCompletedBuild) {
private TestResultActionIterable createBuildHistory(final Run<?, ?> lastCompletedBuild) {
// some plugins that depend on junit seem to attach the action even though there's no run
// e.g. xUnit and cucumber
if (lastCompletedBuild == null) {
Expand All @@ -153,11 +161,11 @@ private TestResultActionIterable createBuildHistory(Run<?, ?> lastCompletedBuild

/**
* Display the test result trend.
*
*
* @deprecated Replaced by echarts in TODO
*/
@Deprecated
public void doTrend( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
public void doTrend( final StaplerRequest req, final StaplerResponse rsp ) throws IOException, ServletException {
AbstractTestResultAction a = getLastTestResultAction();
if(a!=null)
a.doGraph(req,rsp);
Expand All @@ -171,7 +179,7 @@ public void doTrend( StaplerRequest req, StaplerResponse rsp ) throws IOExceptio
* @deprecated Replaced by echarts in TODO
*/
@Deprecated
public void doTrendMap( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
public void doTrendMap( final StaplerRequest req, final StaplerResponse rsp ) throws IOException, ServletException {
AbstractTestResultAction a = getLastTestResultAction();
if(a!=null)
a.doGraphMap(req,rsp);
Expand All @@ -182,7 +190,7 @@ public void doTrendMap( StaplerRequest req, StaplerResponse rsp ) throws IOExcep
/**
* Changes the test result report display mode.
*/
public void doFlipTrend( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
public void doFlipTrend( final StaplerRequest req, final StaplerResponse rsp ) throws IOException, ServletException {
boolean failureOnly = false;

// check the current preference value
Expand All @@ -200,7 +208,7 @@ public void doFlipTrend( StaplerRequest req, StaplerResponse rsp ) throws IOExce
// set the updated value
Cookie cookie = new Cookie(FAILURE_ONLY_COOKIE,String.valueOf(failureOnly));
List<Ancestor> anc = req.getAncestors();
Ancestor a = (Ancestor) anc.get(anc.size()-2);
Ancestor a = anc.get(anc.size()-2);
cookie.setPath(a.getUrl()); // just for this project
cookie.setMaxAge(60*60*24*365); // 1 year
rsp.addCookie(cookie);
Expand All @@ -211,12 +219,17 @@ public void doFlipTrend( StaplerRequest req, StaplerResponse rsp ) throws IOExce

private static final String FAILURE_ONLY_COOKIE = "TestResultAction_failureOnly";

@JavaScriptMethod
@Override
@Override @Deprecated
public String getBuildTrendModel() {
return new JacksonFacade().toJson(createChartModel());
}

@JavaScriptMethod
@Override
public String getConfigurableBuildTrendModel(final String configuration) {
return new JacksonFacade().toJson(createChartModel(ChartModelConfiguration.fromJson(configuration)));
}

@Override
public boolean isTrendVisible() {
return true;
Expand Down
23 changes: 10 additions & 13 deletions src/main/java/hudson/tasks/test/TestResultTrendChart.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
package hudson.tasks.test;

import java.util.List;

import edu.hm.hafner.echarts.ChartModelConfiguration;
import edu.hm.hafner.echarts.LineSeries;
import edu.hm.hafner.echarts.LinesChartModel;
import edu.hm.hafner.echarts.LinesDataSet;
import edu.hm.hafner.echarts.Palette;
import edu.umd.cs.findbugs.annotations.NonNull;

import hudson.tasks.junit.TrendTestResultSummary;
import java.util.List;

import static hudson.tasks.test.TestResultTrendSeriesBuilder.FAILED_KEY;
import static hudson.tasks.test.TestResultTrendSeriesBuilder.PASSED_KEY;
import static hudson.tasks.test.TestResultTrendSeriesBuilder.SKIPPED_KEY;
import static hudson.tasks.test.TestResultTrendSeriesBuilder.*;

public class TestResultTrendChart {
public LinesChartModel create(List<TrendTestResultSummary> results) {

public LinesChartModel create(final List<TrendTestResultSummary> results) {
LinesDataSet dataset = new LinesDataSet();
results.forEach(result -> dataset.add(result.getDisplayName(), result.toMap(), result.getBuildNumber()));

return getLinesChartModel(dataset);
}

Expand All @@ -29,7 +29,7 @@ public LinesChartModel create(@NonNull final Iterable results,

return getLinesChartModel(dataSet);
}

public LinesChartModel createFromTestObject(final Iterable results,
final ChartModelConfiguration configuration) {
TestObjectTrendSeriesBuilder builder = new TestObjectTrendSeriesBuilder();
Expand All @@ -38,11 +38,8 @@ public LinesChartModel createFromTestObject(final Iterable results,
return getLinesChartModel(dataSet);
}

private LinesChartModel getLinesChartModel(LinesDataSet dataSet) {
LinesChartModel model = new LinesChartModel();
model.setDomainAxisLabels(dataSet.getDomainAxisLabels());
model.setBuildNumbers(dataSet.getBuildNumbers());

private LinesChartModel getLinesChartModel(final LinesDataSet dataSet) {
LinesChartModel model = new LinesChartModel(dataSet);
LineSeries failed = new LineSeries("Failed", Palette.RED.getNormal(),
LineSeries.StackedMode.STACKED, LineSeries.FilledMode.FILLED);
failed.addAll(dataSet.getSeries(FAILED_KEY));
Expand Down
Loading

0 comments on commit 433a2d8

Please sign in to comment.