diff --git a/CHANGELOG.md b/CHANGELOG.md index 63041642dd..e73e41446d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v0.7.2 + +## New Features + +* Added `cssClass` and `color` attributes to `@IsTag` to customize tags in HTML reports [#69](https://github.com/TNG/JGiven/pull/69) + +## Fixed Issues + +* Custom CSS files are now copied to the target folder when generating HTML5 reports [#70](https://github.com/TNG/JGiven/issues/70) + # v0.7.1 ## New Features diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/annotation/IsTag.java b/jgiven-core/src/main/java/com/tngtech/jgiven/annotation/IsTag.java index 201eb87907..8c62474a4e 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/annotation/IsTag.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/annotation/IsTag.java @@ -79,4 +79,30 @@ * Whether the type should be prepended to the tag if the tag has a value. */ boolean prependType() default false; + + /** + * Sets a CSS class that should be used in HTML reports for this tag. + *

+ * The default CSS class is {@code 'tag-'} where {@code } is the type of the tag + *

+ * Non-HTML reports ignore this attribute + * + * @since 0.7.2 + */ + String cssClass() default ""; + + /** + * A color that should be used in reports for this tag. + *

+ * It depends on the type of the report whether and how this value is interpreted. + * HTML reports take this value as the background color for the tag. + *

+ * Example values for the HTML report are 'red', '#ff0000', 'rgba(100,0,0,0.5)' + *

+ * This attribute is for simple use cases. + * For advanced styling options use the {@link #cssClass()} attribute instead. + * + * @since 0.7.2 + */ + String color() default ""; } diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/config/TagConfiguration.java b/jgiven-core/src/main/java/com/tngtech/jgiven/config/TagConfiguration.java index e87544ecc8..ec4c58d18f 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/config/TagConfiguration.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/config/TagConfiguration.java @@ -15,6 +15,8 @@ public class TagConfiguration { private boolean prependType; private String defaultValue = ""; private String description = ""; + private String color = ""; + private String cssClass = ""; private Class descriptionGenerator = DefaultTagDescriptionGenerator.class; private String type = ""; @@ -59,6 +61,17 @@ public Builder prependType( boolean b ) { configuration.prependType = b; return this; } + + public Builder cssClass( String cssClass ) { + configuration.cssClass = cssClass; + return this; + } + + public Builder color( String color ) { + configuration.color = color; + return this; + } + } /** @@ -117,6 +130,22 @@ public boolean isPrependType() { return prependType; } + /** + * {@link com.tngtech.jgiven.annotation.IsTag#color()} + * @see com.tngtech.jgiven.annotation.IsTag + */ + public String getColor() { + return color; + } + + /** + * {@link com.tngtech.jgiven.annotation.IsTag#cssClass()} + * @see com.tngtech.jgiven.annotation.IsTag + */ + public String getCssClass() { + return cssClass; + } + public static TagConfiguration fromIsTag( IsTag isTag ) { TagConfiguration result = new TagConfiguration(); result.defaultValue = isTag.value(); @@ -126,6 +155,8 @@ public static TagConfiguration fromIsTag( IsTag isTag ) { result.prependType = isTag.prependType(); result.type = isTag.type(); result.descriptionGenerator = isTag.descriptionGenerator(); + result.cssClass = isTag.cssClass(); + result.color = isTag.color(); return result; } } diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/report/ReportGenerator.java b/jgiven-core/src/main/java/com/tngtech/jgiven/report/ReportGenerator.java index 1fd670f05d..3451a83dea 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/report/ReportGenerator.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/report/ReportGenerator.java @@ -110,11 +110,15 @@ public void generate() throws Exception { private void generateStaticHtmlReport( CompleteReportModel reportModel ) throws IOException { new StaticHtmlReportGenerator().generate( reportModel, getTargetDirectory() ); + copyCustomCssFile( getTargetDirectory() ); + } + + private void copyCustomCssFile( File targetDirectory ) throws IOException { if( getCustomCssFile() != null ) { if( !getCustomCssFile().canRead() ) { log.info( "Cannot read customCssFile " + getCustomCssFile() + " skipping" ); } else { - Files.copy( getCustomCssFile(), new File( getTargetDirectory(), "custom.css" ) ); + Files.copy( getCustomCssFile(), new File( targetDirectory, "custom.css" ) ); } } } @@ -132,6 +136,7 @@ private void generateHtml5Report( CompleteReportModel reportModel ) throws IOExc } reportGenerator.generate( reportModel, getTargetDirectory() ); + copyCustomCssFile( new File( getTargetDirectory(), "css" ) ); } private static void printUsageAndExit() { diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/report/html/HtmlTocWriter.java b/jgiven-core/src/main/java/com/tngtech/jgiven/report/html/HtmlTocWriter.java index d5c5211d2d..1f888399f3 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/report/html/HtmlTocWriter.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/report/html/HtmlTocWriter.java @@ -8,7 +8,6 @@ import java.util.List; import com.google.common.base.Function; -import com.google.common.base.Joiner; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimaps; @@ -159,14 +158,7 @@ private void writeTagLink( Tag tag, List list ) { } static String tagToFilename( Tag tag ) { - List fileNameParts = Lists.newArrayList( tag.getName() ); - fileNameParts.addAll( tag.getValues() ); - String fileName = escape( Joiner.on( '-' ).join( fileNameParts ) ); - return fileName.substring( 0, Math.min( fileName.length(), 255 ) ) + ".html"; - } - - static String escape( String string ) { - return string.replaceAll( "[^\\p{Alnum}-]", "_" ); + return tag.toEscapedString() + ".html"; } } diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/report/html/ScenarioHtmlWriter.java b/jgiven-core/src/main/java/com/tngtech/jgiven/report/html/ScenarioHtmlWriter.java index 9e5f4513ac..dac79aafde 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/report/html/ScenarioHtmlWriter.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/report/html/ScenarioHtmlWriter.java @@ -81,8 +81,13 @@ private void printTag( Tag tag ) { } public static String tagToHtml( Tag tag ) { - return format( "

%s
", - tag.getName(), HtmlTocWriter.tagToFilename( tag ), tag.toString() ); + return format( "
%s
", + tag.getCssClassOrDefault(), getColorAttribute( tag ), HtmlTocWriter.tagToFilename( tag ), tag.toString() ); + } + + private static String getColorAttribute( Tag tag ) { + return tag.getColor() == null ? "" + : " style='background-color: " + tag.getColor() + "'"; } @Override @@ -119,7 +124,7 @@ void printCaseHeader( ScenarioCaseModel scenarioCase ) { if( scenarioModel.getScenarioCases().size() > 1 ) { writer.print( format( "

", getCaseId() ) ); writeStatusIcon( scenarioCase.success ); - writer.print( format( " Case %d: ", scenarioCase.getCaseNr()) ); + writer.print( format( " Case %d: ", scenarioCase.getCaseNr() ) ); for( int i = 0; i < scenarioCase.getExplicitArguments().size(); i++ ) { if( scenarioModel.getExplicitParameters().size() > i ) { diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/ReportModelBuilder.java b/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/ReportModelBuilder.java index bd82160aba..c31ee06613 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/ReportModelBuilder.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/ReportModelBuilder.java @@ -354,6 +354,14 @@ public List toTags( Annotation annotation ) { tag.setPrependType( true ); } + if( !Strings.isNullOrEmpty( tagConfig.getCssClass() ) ) { + tag.setCssClass( tagConfig.getCssClass() ); + } + + if( !Strings.isNullOrEmpty( tagConfig.getColor() ) ) { + tag.setColor( tagConfig.getColor() ); + } + Object value = tagConfig.getDefaultValue(); if( !Strings.isNullOrEmpty( tagConfig.getDefaultValue() ) ) { tag.setValue( tagConfig.getDefaultValue() ); @@ -414,6 +422,8 @@ private List getExplodedTags( Tag originalTag, Object[] values, Annotation newTag.setDescription( originalTag.getDescription() ); newTag.setPrependType( originalTag.isPrependType() ); newTag.setDescription( getDescriptionFromGenerator( tagConfig, annotation, singleValue ) ); + newTag.setColor( originalTag.getColor() ); + newTag.setCssClass( originalTag.getCssClass() ); result.add( newTag ); } return result; diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/Tag.java b/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/Tag.java index 41e66f597e..2ee4b18a32 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/Tag.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/Tag.java @@ -11,6 +11,9 @@ * A tag represents a Java annotation of a scenario-test. */ public class Tag { + /** + * The name/type of this tag + */ private final String name; /** @@ -26,8 +29,20 @@ public class Tag { /** * Whether the type should be prepended in the report. + *

+ * Is either {@code true} or {@code null} + */ + private Boolean prependType; + + /** + * An optional color that is used in reports + */ + private String color; + + /** + * An optional cssClass used in HTML reports */ - private boolean prependType; + private String cssClass; public Tag( String name ) { this.name = name; @@ -43,7 +58,7 @@ public String getName() { } public boolean isPrependType() { - return prependType; + return prependType == null ? false : true; } public String getDescription() { @@ -54,6 +69,26 @@ public void setDescription( String description ) { this.description = description; } + public void setColor( String color ) { + this.color = color; + } + + public String getColor() { + return color; + } + + public void setCssClass( String cssClass ) { + this.cssClass = cssClass; + } + + public String getCssClass() { + return cssClass; + } + + public String getCssClassOrDefault() { + return cssClass == null ? "tag-" + getName() : cssClass; + } + @SuppressWarnings( "unchecked" ) public List getValues() { if( value == null ) { @@ -74,7 +109,7 @@ public void setValue( String value ) { } public Tag setPrependType( boolean prependType ) { - this.prependType = prependType; + this.prependType = prependType ? true : null; return this; } @@ -82,7 +117,7 @@ public Tag setPrependType( boolean prependType ) { public String toString() { if( value != null ) { String valueString = getValueString(); - if( prependType ) { + if( isPrependType() ) { return getName() + "-" + valueString; } return valueString; @@ -118,4 +153,20 @@ public boolean equals( Object obj ) { && Objects.equal( value, other.value ); } + /** + * Returns a string representation where all non-alphanumeric characters are replaced with an underline (_). + * In addition, the result is cut-off at a length of 255 characters. + * + * @return a string representation without special characters + */ + public String toEscapedString() { + List parts = Lists.newArrayList( getName() ); + parts.addAll( getValues() ); + String escapedString = escape( Joiner.on( '-' ).join( parts ) ); + return escapedString.substring( 0, Math.min( escapedString.length(), 255 ) ); + } + + static String escape( String string ) { + return string.replaceAll( "[^\\p{Alnum}-]", "_" ); + } } diff --git a/jgiven-html5-report/src/app/app.js b/jgiven-html5-report/src/app/app.js index 2bc5adbe47..c797ab2727 100644 --- a/jgiven-html5-report/src/app/app.js +++ b/jgiven-html5-report/src/app/app.js @@ -455,7 +455,6 @@ jgivenReportApp.controller('JGivenReportCtrl', function ($scope, $rootScope, $ti function getTags() { var res = {}; var key; - var scenarioList; var tagEntry; _.forEach(jgivenReport.scenarios, function(testCase) { _.forEach(testCase.scenarios, function(scenario) { @@ -501,6 +500,23 @@ jgivenReportApp.controller('JGivenReportCtrl', function ($scope, $rootScope, $ti return res; }; + $scope.getCssClassOfTag = function getCssClassOfTag( tag ) { + if (tag.cssClass) { + return tag.cssClass; + } + return 'tag-' + tag.name; + }; + + /** + * Returns the content of style attribute for the given tag + */ + $scope.getStyleOfTag = function getStyleOfTag( tag ) { + if (tag.color) { + return 'background-color: '+tag.color; + } + return ''; + }; + $scope.isHeaderCell = function( rowIndex, columnIndex, headerType ) { console.log(headerType); if (rowIndex === 0 && (headerType === 'HORIZONTAL' || headerType === 'BOTH')) { diff --git a/jgiven-html5-report/src/app/index.html b/jgiven-html5-report/src/app/index.html index e62d99539e..180f10713a 100644 --- a/jgiven-html5-report/src/app/index.html +++ b/jgiven-html5-report/src/app/index.html @@ -307,8 +307,8 @@

Cases
diff --git a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/WhenHtml5Report.java b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/WhenHtml5Report.java index 1f9c5bb8ab..b4cdb6385f 100644 --- a/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/WhenHtml5Report.java +++ b/jgiven-tests/src/test/java/com/tngtech/jgiven/report/html5/WhenHtml5Report.java @@ -37,11 +37,11 @@ public SELF the_All_Scenarios_page_is_opened() throws MalformedURLException { } public SELF the_tag_with_name_$_is_clicked( String tagName ) { - List tags = webDriver.findElements( By.className( "tag" ) ); - for( WebElement element : tags ) { - WebElement a = element.findElement( By.linkText( tagName ) ); - if( a != null ) { - a.click(); + List links = webDriver.findElements( By.linkText( tagName ) ); + for( WebElement link : links ) { + WebElement tag = link.findElement( By.className( "tag" ) ); + if( tag != null ) { + link.click(); break; } }