![JAR search and dependency download from the Maven repository](/logo.png)
com.trivago.cluecumber.engine.properties.PropertyManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cluecumber-engine Show documentation
Show all versions of cluecumber-engine Show documentation
The Cluecumber reporting engine.
The newest version!
/*
* Copyright 2023 trivago N.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.trivago.cluecumber.engine.properties;
import com.trivago.cluecumber.engine.constants.Navigation;
import com.trivago.cluecumber.engine.constants.Settings;
import com.trivago.cluecumber.engine.exceptions.CluecumberException;
import com.trivago.cluecumber.engine.exceptions.filesystem.MissingFileException;
import com.trivago.cluecumber.engine.exceptions.properties.WrongOrMissingPropertyException;
import com.trivago.cluecumber.engine.filesystem.FileIO;
import com.trivago.cluecumber.engine.logging.CluecumberLogger;
import com.trivago.cluecumber.engine.rendering.pages.pojos.pagecollections.Link;
import com.trivago.cluecumber.engine.rendering.pages.pojos.pagecollections.LinkType;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import static com.trivago.cluecumber.engine.logging.CluecumberLogger.CluecumberLogLevel.COMPACT;
import static com.trivago.cluecumber.engine.logging.CluecumberLogger.CluecumberLogLevel.DEFAULT;
/**
* This class stores and serves all Cluecumber properties.
*/
@Singleton
public class PropertyManager {
private static final String COLOR_PATTERN = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$";
private final CluecumberLogger logger;
private final FileIO fileIO;
private final PropertiesFileLoader propertiesFileLoader;
private final Map customParameters = new LinkedHashMap<>();
private final Map customNavigationLinks = new LinkedHashMap<>();
private String sourceJsonReportDirectory;
private String generatedHtmlReportDirectory;
private boolean failScenariosOnPendingOrUndefinedSteps = false;
private boolean expandSubSections = false;
private boolean expandBeforeAfterHooks = false;
private boolean expandStepHooks = false;
private boolean expandDocStrings = false;
private boolean expandAttachments = true;
private boolean expandOutputs = false;
private boolean groupPreviousScenarioRuns = false;
private boolean expandPreviousScenarioRuns = false;
private String customCssFile;
private String customFaviconFile;
private String customParametersFile;
private Settings.CustomParamDisplayMode customParametersDisplayMode =
Settings.CustomParamDisplayMode.ALL_PAGES;
private String customStatusColorPassed = "#60cc79";
private String customStatusColorFailed = "#fc7180";
private String customStatusColorSkipped = "#f7c42b";
private String customPageTitle = "Cluecumber Report";
private Settings.StartPage startPage = Settings.StartPage.ALL_SCENARIOS;
/**
* Constructor for dependency injection.
*
* @param logger The {@link CluecumberLogger} instance.
* @param fileIO The {@link FileIO} instance.
* @param propertiesFileLoader The {@link PropertiesFileLoader} instance.
*/
@Inject
public PropertyManager(
final CluecumberLogger logger,
final FileIO fileIO,
final PropertiesFileLoader propertiesFileLoader
) {
this.logger = logger;
this.fileIO = fileIO;
this.propertiesFileLoader = propertiesFileLoader;
}
/**
* Get the root directory of the source JSON files.
*
* @return The path.
*/
public String getSourceJsonReportDirectory() {
return sourceJsonReportDirectory;
}
/**
* Set the root directory of the source JSON files.
*
* @param sourceJsonReportDirectory The path.
* @throws WrongOrMissingPropertyException Thrown on any error.
*/
public void setSourceJsonReportDirectory(final String sourceJsonReportDirectory)
throws WrongOrMissingPropertyException {
if (!isSet(sourceJsonReportDirectory)) {
throw new WrongOrMissingPropertyException("sourceJsonReportDirectory");
}
this.sourceJsonReportDirectory = sourceJsonReportDirectory;
}
/**
* Get the root directory of the target HTML report.
*
* @return The path.
*/
public String getGeneratedHtmlReportDirectory() {
return generatedHtmlReportDirectory;
}
/**
* Set the root directory of the target HTML report.
*
* @param generatedHtmlReportDirectory The path.
* @throws WrongOrMissingPropertyException Thrown on any error.
*/
public void setGeneratedHtmlReportDirectory(final String generatedHtmlReportDirectory)
throws WrongOrMissingPropertyException {
if (!isSet(generatedHtmlReportDirectory)) {
throw new WrongOrMissingPropertyException("generatedHtmlReportDirectory");
}
this.generatedHtmlReportDirectory = generatedHtmlReportDirectory;
}
/**
* Get the custom parameters to be shown at the top of the report.
*
* @return The map of custom parameter key value pairs.
*/
public Map getCustomParameters() {
return customParameters;
}
/**
* Set the custom parameters to be shown at the top of the report.
*
* @param customParameters The map of custom parameter key value pairs.
*/
public void setCustomParameters(final Map customParameters) {
this.customParameters.putAll(customParameters);
}
/**
* Get the path to the custom parameter file.
*
* @return The path as string.
*/
public String getCustomParametersFile() {
return customParametersFile;
}
/**
* Set the path to the custom parameter file.
*
* @param customParametersFile The path as string.
* @throws CluecumberException Thrown on every error.
*/
public void setCustomParametersFile(String customParametersFile) throws CluecumberException {
this.customParametersFile = customParametersFile;
if (!isSet(customParametersFile)) {
return;
}
if (!fileIO.isExistingFile(customParametersFile)) {
throw new MissingFileException(customParametersFile + " (customParametersFile)");
}
Map customParameters = propertiesFileLoader.loadPropertiesMap(customParametersFile);
this.customParameters.putAll(customParameters);
}
/**
* Get the display mode for custom parameters (on which page they should appear).
*
* @return The {@link com.trivago.cluecumber.engine.constants.Settings.CustomParamDisplayMode} value.
*/
public Settings.CustomParamDisplayMode getCustomParametersDisplayMode() {
return customParametersDisplayMode;
}
/**
* Set the display mode for custom parameters (on which page they should appear).
* Must be a value of {@link com.trivago.cluecumber.engine.constants.Settings.CustomParamDisplayMode}.
*
* @param customParametersDisplayMode The display mode string.
*/
public void setCustomParametersDisplayMode(String customParametersDisplayMode) {
try {
this.customParametersDisplayMode =
Settings.CustomParamDisplayMode.valueOf(customParametersDisplayMode.toUpperCase());
} catch (IllegalArgumentException e) {
logger.warn("Unknown setting for custom parameter page(s): '" + customParametersDisplayMode +
"'. Must be one of " + Arrays.toString(Settings.CustomParamDisplayMode.values()));
this.customParametersDisplayMode = Settings.CustomParamDisplayMode.SCENARIO_PAGES;
}
}
/**
* Set the custom navigation links to appear next to the default Cluecumber navigation.
* The map key represents the caption to be display in the navigation, the value is the actual URL to link to.
*
* @param customNavigationLinks The map of key value pairs.
*/
public void setCustomNavigationLinks(final Map customNavigationLinks) {
if (customNavigationLinks == null) {
return;
}
this.customNavigationLinks.putAll(customNavigationLinks);
}
/**
* Get the custom navigation links to appear next to the default Cluecumber navigation.
* The map key represents the caption to be display in the navigation, the value is the actual URL to link to.
*
* @return The map of key value pairs.
*/
public List getNavigationLinks() {
List links = new LinkedList<>(Navigation.internalLinks);
customNavigationLinks.forEach((key, value) -> {
String linkName = key.replace("_", " ");
links.add(new Link(linkName, value, LinkType.EXTERNAL));
});
links.removeIf(link -> !groupPreviousScenarioRuns && link.getName().equals("rerun_scenarios"));
return links;
}
/**
* This determines whether a scenario should be considered failed if it contains pending or undefined steps.
*
* @return true means fail on pending or undefined steps.
*/
public boolean isFailScenariosOnPendingOrUndefinedSteps() {
return failScenariosOnPendingOrUndefinedSteps;
}
/**
* Set whether a scenario should be considered failed if it contains pending or undefined steps.
*
* @param failScenariosOnPendingOrUndefinedSteps true means fail on pending or undefined steps.
*/
public void setFailScenariosOnPendingOrUndefinedSteps(final boolean failScenariosOnPendingOrUndefinedSteps) {
this.failScenariosOnPendingOrUndefinedSteps = failScenariosOnPendingOrUndefinedSteps;
}
/**
* This determines whether sub sections should be expanded by default.
*
* @return true means they should be expanded.
*/
public boolean isExpandSubSections() {
return expandSubSections;
}
/**
* Set whether sub sections should be expanded by default.
*
* @param expandSubSections true means they should be expanded.
*/
public void setExpandSubSections(final boolean expandSubSections) {
this.expandSubSections = expandSubSections;
}
/**
* This determines whether before and after hooks should be expanded by default.
*
* @return true means they should be expanded.
*/
public boolean isExpandBeforeAfterHooks() {
return expandBeforeAfterHooks;
}
/**
* Set whether before and after hooks should be expanded by default.
*
* @param expandBeforeAfterHooks true means they should be expanded.
*/
public void setExpandBeforeAfterHooks(final boolean expandBeforeAfterHooks) {
this.expandBeforeAfterHooks = expandBeforeAfterHooks;
}
/**
* This determines whether step hooks should be expanded by default.
*
* @return true means they should be expanded.
*/
public boolean isExpandStepHooks() {
return expandStepHooks;
}
/**
* Set whether step hooks should be expanded by default.
*
* @param expandStepHooks true means they should be expanded.
*/
public void setExpandStepHooks(final boolean expandStepHooks) {
this.expandStepHooks = expandStepHooks;
}
/**
* This determines whether doc strings should be expanded by default.
*
* @return true means they should be expanded.
*/
public boolean isExpandDocStrings() {
return expandDocStrings;
}
/**
* Set whether doc strings should be expanded by default.
*
* @param expandDocStrings true means they should be expanded.
*/
public void setExpandDocStrings(final boolean expandDocStrings) {
this.expandDocStrings = expandDocStrings;
}
/**
* This determines whether attachments should be expanded by default.
*
* @return true means they should be expanded.
*/
public boolean isExpandAttachments() {
return expandAttachments;
}
/**
* This determines whether step outputs should be expanded by default.
*
* @return true means they should be expanded.
*/
public boolean isExpandOutputs() {
return expandOutputs;
}
/**
* Set whether attachments should be expanded by default.
*
* @param expandAttachments true means they should be expanded.
*/
public void setExpandAttachments(final boolean expandAttachments) {
this.expandAttachments = expandAttachments;
}
/**
* Set whether step outputs should be expanded by default.
*
* @param expandOutputs true means they should be expanded.
*/
public void setExpandOutputs(final boolean expandOutputs) {
this.expandOutputs = expandOutputs;
}
/**
* This determines whether the scenarios run multiple times should be grouped and the show not last run toggle should be shown.
*
* @return true means scenarios should be grouped and toggle should be shown.
*/
public boolean isGroupPreviousScenarioRuns() {
return groupPreviousScenarioRuns;
}
/**
* Set whether the scenarios run multiple times should be grouped and the show not last run toggle should be shown.
*
* @param groupPreviousScenarioRuns true means scenarios should be grouped and toggle should be shown.
*/
public void setGroupPreviousScenarioRuns(final boolean groupPreviousScenarioRuns) {
this.groupPreviousScenarioRuns = groupPreviousScenarioRuns;
}
/**
* This determines whether the not last run elements should be expanded and shown.
*
* @return true means it should be expanded.
*/
public boolean isExpandPreviousScenarioRuns() {
return expandPreviousScenarioRuns;
}
/**
* Set whether the not last run elements should be expanded and shown.
*
* @param expandPreviousScenarioRuns true means elements should be expanded.
*/
public void setExpandPreviousScenarioRuns(final boolean expandPreviousScenarioRuns) {
this.expandPreviousScenarioRuns = expandPreviousScenarioRuns;
}
/**
* Get the custom CSS file path.
*
* @return The path.
*/
public String getCustomCssFile() {
return customCssFile;
}
/**
* Set the custom CSS file path.
*
* @param customCssFile The path.
* @throws MissingFileException Thrown if the file is not found.
*/
public void setCustomCssFile(final String customCssFile) throws MissingFileException {
this.customCssFile = customCssFile;
if (!isSet(customCssFile)) {
return;
}
if (!fileIO.isExistingFile(customCssFile)) {
throw new MissingFileException(customCssFile + " (customCssFile)");
}
}
/**
* Get the custom favicon file path.
*
* @return The path.
*/
public String getCustomFaviconFile() {
return customFaviconFile;
}
/**
* Set the custom favicon file path.
*
* @param customFaviconFile The path.
* @throws MissingFileException Thrown if the file is not found.
*/
public void setCustomFaviconFile(final String customFaviconFile) throws MissingFileException {
this.customFaviconFile = customFaviconFile;
if (!isSet(customFaviconFile)) {
return;
}
if (!fileIO.isExistingFile(customFaviconFile)) {
throw new MissingFileException(customFaviconFile + " (customFaviconFile)");
}
}
/**
* Get the custom hex color for passed elements.
*
* @return The hex color string.
*/
public String getCustomStatusColorPassed() {
return this.customStatusColorPassed;
}
/**
* Set a custom hex color for passed elements.
*
* @param customStatusColorPassed The color as a hex string (e.g. '#00ff00').
* @throws WrongOrMissingPropertyException Thrown on any error.
*/
public void setCustomStatusColorPassed(final String customStatusColorPassed) throws WrongOrMissingPropertyException {
if (!isSet(customStatusColorPassed)) return;
checkHexColorValidity(customStatusColorPassed, "customStatusColorPassed");
this.customStatusColorPassed = customStatusColorPassed;
}
/**
* Get the custom hex color for failed elements.
*
* @return The hex color string.
*/
public String getCustomStatusColorFailed() {
return this.customStatusColorFailed;
}
/**
* Set a custom hex color for failed elements.
*
* @param customStatusColorFailed The color as a hex string (e.g. '#00ff00').
* @throws WrongOrMissingPropertyException Thrown on any error.
*/
public void setCustomStatusColorFailed(final String customStatusColorFailed) throws WrongOrMissingPropertyException {
if (!isSet(customStatusColorFailed)) return;
checkHexColorValidity(customStatusColorFailed, "customStatusColorFailed");
this.customStatusColorFailed = customStatusColorFailed;
}
/**
* Get the custom hex color for skipped elements.
*
* @return The hex color string.
*/
public String getCustomStatusColorSkipped() {
return this.customStatusColorSkipped;
}
/**
* Set a custom hex color for skipped elements.
*
* @param customStatusColorSkipped The color as a hex string (e.g. '#00ff00').
* @throws WrongOrMissingPropertyException Thrown on any error.
*/
public void setCustomStatusColorSkipped(final String customStatusColorSkipped) throws WrongOrMissingPropertyException {
if (!isSet(customStatusColorSkipped)) return;
checkHexColorValidity(customStatusColorSkipped, "customStatusColorSkipped");
this.customStatusColorSkipped = customStatusColorSkipped;
}
/**
* Get the custom page title of the report.
*
* @return The page title.
*/
public String getCustomPageTitle() {
return this.customPageTitle;
}
/**
* Set the custom page title of the report.
*
* @param customPageTitle The page title.
*/
public void setCustomPageTitle(final String customPageTitle) {
if (isSet(customPageTitle)) {
this.customPageTitle = customPageTitle;
}
}
/**
* Log Cluecumber properties on the command line based on the set log level.
*/
public void logProperties() {
logger.info("- source JSON report directory : " + sourceJsonReportDirectory, DEFAULT, COMPACT);
logger.info("- generated HTML report directory : " + generatedHtmlReportDirectory, DEFAULT, COMPACT);
boolean customParametersFileExists = isSet(customParametersFile);
if (customParametersFileExists) {
logger.logInfoSeparator(DEFAULT);
logger.info("- custom parameters file : " + customParametersFile, DEFAULT);
}
if (!customParameters.isEmpty()) {
if (!customParametersFileExists) {
logger.logInfoSeparator();
}
customParameters.entrySet().stream().map(entry -> "- custom parameter : " +
entry.getKey() + " -> " +
entry.getValue()).forEach(
logString -> logger.info(logString, DEFAULT));
}
logger.logInfoSeparator(DEFAULT);
logger.info("- fail pending/undefined scenarios : " + failScenariosOnPendingOrUndefinedSteps, DEFAULT);
logger.info("- expand sub sections : " + expandSubSections, DEFAULT);
logger.info("- expand before/after hooks : " + expandBeforeAfterHooks, DEFAULT);
logger.info("- expand step hooks : " + expandStepHooks, DEFAULT);
logger.info("- expand doc strings : " + expandDocStrings, DEFAULT);
logger.info("- expand step outputs : " + expandOutputs, DEFAULT);
logger.info("- expand attachments : " + expandAttachments, DEFAULT);
logger.info("- page title : " + customPageTitle, DEFAULT);
logger.info("- start page : " + startPage, DEFAULT);
logger.info("- custom parameters display mode : " + customParametersDisplayMode, DEFAULT);
logger.info("- group previous scenario runs : " + groupPreviousScenarioRuns, DEFAULT);
logger.info("- expand previous scenario runs : " + expandPreviousScenarioRuns, DEFAULT);
if (!customNavigationLinks.isEmpty()) {
customNavigationLinks.entrySet().stream().map(
entry -> "- custom navigation link : " +
entry.getKey() + " -> " + entry.getValue()).forEach(
logString -> logger.info(logString, DEFAULT));
}
if (isSet(customCssFile)) {
logger.info("- custom CSS file : " + customCssFile, DEFAULT);
}
if (isSet(customFaviconFile)) {
logger.info("- custom favicon file : " + customFaviconFile, DEFAULT);
}
logger.info("- colors (passed, failed, skipped) : " +
customStatusColorPassed + ", " + customStatusColorFailed + ", " + customStatusColorSkipped, DEFAULT);
logger.logInfoSeparator(DEFAULT);
}
/**
* Check if a string is set.
*
* @param string The string to check.
* @return true if the string is set.
*/
private boolean isSet(final String string) {
return string != null && !string.trim().isEmpty();
}
/**
* Check if a hex color is valid.
*
* @param color The color string.
* @param colorPropertyName The name of the color property.
* @throws WrongOrMissingPropertyException Thrown if the color is invalid.
*/
private void checkHexColorValidity(String color, String colorPropertyName)
throws WrongOrMissingPropertyException {
if (!Pattern.compile(COLOR_PATTERN).matcher(color).matches()) {
throw new WrongOrMissingPropertyException(colorPropertyName);
}
}
/**
* Get the start page of the report.
*
* @return The {@link com.trivago.cluecumber.engine.constants.Settings.StartPage} value.
*/
public Settings.StartPage getStartPage() {
return startPage;
}
/**
* Set the start page of the report.
*
* @param startPage The name of the start page (must be included in the {@link com.trivago.cluecumber.engine.constants.Settings.StartPage} enum.
*/
public void setStartPage(final String startPage) {
try {
this.startPage = Settings.StartPage.valueOf(startPage.toUpperCase());
} catch (IllegalArgumentException e) {
logger.warn("Unknown start page '" + startPage + "'. Must be one of " +
Arrays.toString(Settings.StartPage.values()));
this.startPage = Settings.StartPage.ALL_SCENARIOS;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy