
core.support.logger.TestLog Maven / Gradle / Ivy
package core.support.logger;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.sound.sampled.AudioInputStream;
import javax.xml.xpath.XPathExpressionException;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.slf4j.LoggerFactory;
import org.testng.util.Strings;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.gherkin.model.And;
import com.aventstack.extentreports.gherkin.model.Background;
import com.aventstack.extentreports.gherkin.model.But;
import com.aventstack.extentreports.gherkin.model.Given;
import com.aventstack.extentreports.gherkin.model.Then;
import com.aventstack.extentreports.gherkin.model.When;
import com.aventstack.extentreports.markuputils.ExtentColor;
import com.aventstack.extentreports.markuputils.Markup;
import com.aventstack.extentreports.markuputils.MarkupHelper;
import core.apiCore.interfaces.RestApiInterface;
import core.helpers.Helper;
import core.helpers.UtilityHelper;
import core.support.configReader.Config;
import core.support.objects.ServiceObject;
import core.support.objects.TestObject;
import core.support.objects.TestObject.testState;
import core.uiCore.driverProperties.globalProperties.CrossPlatformProperties;
import core.uiCore.drivers.AbstractDriver;
import io.restassured.response.Response;
import marytts.LocalMaryInterface;
import marytts.MaryInterface;
public class TestLog {
public static final String ENABLE_EXTENT_SUBSTEPS = "report.enableDetailedReport";
public static final String ENABLE_DEBUG = "console.debug.enable";
public static final String IS_LOG_LIMIT = "log.limit.enabled";
public static final String LOG_MAX_LIMIT = "log.max.limit.char";
public static final String LOG_SKIP_CONSOLE = "console.skip.console.log";
public static String WATSON = "WATSON";
public static String MARY = "MARY";
enum gherkins {
Given, When, Then, And, But, Background
}
static marytts.util.data.audio.AudioPlayer player;
public static final String LOG4JPATH = Config.RESOURCE_PATH + "/log4j2.xml";
/**
* logs to console
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static void ConsoleLogNoLimit(String value, Object... args) {
logConsoleMessage(Level.INFO, formatMessageNoLimit(value, args));
}
/**
* logs to console
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static void ConsoleLog(String value, Object... args) {
logConsoleMessage(Level.INFO, formatMessage(value, args));
}
/**
* logs warning to console
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static void ConsoleLogWarn(String value, Object... args) {
logConsoleMessage(Level.WARN, formatMessage(value, args));
}
/**
* debug logs to console
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static void ConsoleLogDebug(String value, Object... args) {
boolean isDebug = Config.getBooleanValue(ENABLE_DEBUG);
if (isDebug)
logConsoleMessage(Level.WARN, formatMessage(value, args));
}
/**
* error logs to console
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static void ConsoleLogError(String value, Object... args) {
logConsoleMessage(Level.ERROR, formatMessage(value, args));
}
/**
* logs to extent report as background node
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public synchronized static void Background(String value, Object... args) {
setTestStep(gherkins.Background, value, args);
}
/**
* logs to extent report as but node
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public synchronized static void But(String value, Object... args) {
logConsoleMessage(Level.INFO, "But " + formatMessage(value, args));
setTestStep(gherkins.But, value, args);
}
/**
* logs to extent report as given node
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public synchronized static void Given(String value, Object... args) {
logConsoleMessage(Level.INFO, "Given " + formatMessage(value, args));
setTestStep(gherkins.Given, value, args);
}
/**
* logs to extent report as when node
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public synchronized static void When(String value, Object... args) {
logConsoleMessage(Level.INFO, "When " + formatMessage(value, args));
setTestStep(gherkins.When, value, args);
playAudio(gherkins.When.name() + " " + formatMessage(value, args));
}
/**
* logs to extent report as and node
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public synchronized static void And(String value, Object... args) {
logConsoleMessage(Level.INFO, "And " + formatMessage(value, args));
setTestStep(gherkins.And, value, args);
playAudio(gherkins.And.name() + " " + formatMessage(value, args));
}
/**
* logs to extent report as then node
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public synchronized static void Then(String value, Object... args) {
logConsoleMessage(Level.INFO, "Then " + formatMessage(value, args));
setTestStep(gherkins.Then, value, args);
playAudio(gherkins.Then.name() + " " + formatMessage(value, args));
}
/**
* sets test step based on the gherkins language steps: given, when, then, and,
* but, background
*
* @param gherkinState given, when, then, and, but, background
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static synchronized void setTestStep(gherkins gherkinState, String value, Object... args) {
ExtentTest testStep = null;
testState state = TestObject.getTestState(TestObject.getTestInfo().testId);
if (!state.equals(testState.testMethod))
return;
switch (gherkinState) {
case Given:
testStep = getTestScenario().createNode(Given.class, "Given " + formatMessage(value, args)).pass("");
break;
case When:
testStep = getTestScenario().createNode(When.class, "When " + formatMessage(value, args)).pass("");
break;
case Then:
testStep = getTestScenario().createNode(Then.class, "Then " + formatMessage(value, args)).pass("");
break;
case And:
testStep = getTestScenario().createNode(And.class, "And " + formatMessage(value, args)).pass("");
break;
case But:
testStep = getTestScenario().createNode(But.class, "But " + formatMessage(value, args)).pass("");
break;
case Background:
testStep = getTestScenario().createNode(Background.class, formatMessage(value, args)).pass("");
break;
default:
Helper.assertFalse("incorrect state " + gherkinState.name());
}
// if test step is not set, do not log. Test will be set in test method state
// only.
if (TestObject.getTestInfo().testSteps == null)
return;
TestObject.getTestInfo().testSteps.add(testStep);
AbstractDriver.getStep().set(testStep);
}
/**
* sets substep as pass
*
* @param subStep the substep node value
*/
public static void setPassSubTestStep(String subStep) {
if (getTestStep() == null)
return;
testState state = TestObject.getTestState(TestObject.getTestInfo().testId);
if (!state.equals(testState.testMethod))
return;
TestObject.getTestInfo().testSubSteps.add(subStep);
String label = "\r\n" +
" \r\n" +
" Textarea autoresize \r\n" +
" \r\n" +
" \r\n" +
" \r\n" +
" \r\n";
Markup m = MarkupHelper.createLabel(label, ExtentColor.WHITE);
getTestStep().pass(m);
}
/**
* adds video and video link to the sub step
*
* @param path relative path to the video file
* @param isVideoAttached if the video is going to be attached to the extent
* report path : relative path to the video file
*/
public static void attachVideoLog(String path, boolean isVideoAttached) {
testState state = TestObject.getTestState(TestObject.getTestInfo().testId);
if (!state.equals(testState.testMethod))
return;
// for hmtl report, use relative path (we need to be able to email the report)
// for klov we need absolute path
if (!Config.getValue(ExtentManager.REPORT_TYPE).equals(ExtentManager.HTML_REPORT_TYPE))
path = ExtentManager.getReportRootFullPath() + path;
String videoLog = "";
if (isVideoAttached)
getTestStep().pass(videoLog);
getTestStep().pass("screen recording Link");
TestObject.getTestInfo().testSubSteps.add("screen recording relative path: " + path);
}
/**
* link video file to report portal
* currently attaching avi files does not work properly, hence linking url instead
* @param path
*/
public static void attachVideoLogToReportPortal(File video) {
URL url;
try {
url = video.toURI().toURL();
TestLog.ConsoleLog("path to file: ", url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
/**
* log pass is used for test steps for extend report, enable if properties
* option enableDetailedReport is true
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static void logPass(String value, Object... args) {
logConsoleMessage(Level.INFO, formatMessage(value, args));
if (Config.getValue(ENABLE_EXTENT_SUBSTEPS).equals("true")) {
// this will only throw exception with before suite
setPassSubTestStep(formatMessage(value, args));
}
}
/**
* sets fail log for extent report and console
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static void logFail(String value, Object... args) {
logConsoleMessage(Level.ERROR, formatMessage(value, args));
}
/**
* sets warning log for extent report and console
*
* @param value value to log
* @param args additional arguments for logging to be formatted
*/
public static void logWarning(String value, Object... args) {
logConsoleMessage(Level.WARN, formatMessage(value, args));
}
/**
* @return gets the test scenario node
*/
public static ExtentTest getTestScenario() {
return TestObject.getTestInfo().testScenerio;
}
/**
*
* @param value value to log
* @param args additional arguments for logging to be formatted
* @return formatted message based on value and arguments
*/
public static String formatMessageNoLimit(String value, Object... args) {
return formatMessage(value, false, args);
}
/**
*
* @param value value to log
* @param args additional arguments for logging to be formatted
* @return formatted message based on value and arguments
*/
public static String formatMessage(String value, Object... args) {
return formatMessage(value, true, args);
}
/**
*
* @param value value to log
* @param args additional arguments for logging to be formatted
* @return formatted message based on value and arguments
*/
public static String formatMessage(String value, boolean isLimitMessage, Object... args) {
if(isLimitMessage)
value = setMaxLength(value);
if (args == null || args.length == 0) {
return value;
} else {
try {
return new MessageFormat(value).format(args);
} catch (Exception e) {
return value;
}
}
}
/**
* limites the max value size
*
* @param value value to log
* @return truncated message to maximum length
*/
public static String setMaxLength(String value) {
boolean isLogLimit = Config.getBooleanValue(IS_LOG_LIMIT);
int logMaxLimit = Config.getIntValue(LOG_MAX_LIMIT);
if(logMaxLimit == -1) logMaxLimit = value.length();
if(isLogLimit)
return setMaxLength(value, logMaxLimit);
else
return value;
}
/**
*
* @param value value to log
* @param length length to truncate message to
* @return truncated message to maximum length
*/
public static String setMaxLength(String value, int length) {
// limit the max size of string
try {
int maxLength = (value.length() < length) ? value.length() : length;
if (maxLength == length)
return value.substring(0, maxLength) + "...";
return value.substring(0, maxLength);
}catch(Exception e) {
System.out.println("value: " + value);
System.out.println("length: " + length);
e.getMessage();
}
return "";
}
/**
* removes handler for java.util.logging removes logs from third party jars such
* as webdriver
*/
// TODO: temporarily disabled the handler as it conflicts with another log4j
// disabling until issue requiring this occurs again
public static void removeLogUtilHandler() {
// SLF4JBridgeHandler.removeHandlersForRootLogger();
// SLF4JBridgeHandler.install();
}
/**
* sets up log4j loggin
*/
public static void setupLog4j() {
File f = new File(TestLog.LOG4JPATH);
URI fc = f.toURI();
LoggerContext.getContext().setConfigLocation(fc);
// set logging for slf4j logger. applicable to third party loggers
ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(ch.qos.logback.classic.Level.ERROR);
}
/**
* plays audio file based on text value
*
* @param value text value to play back
*/
public static void playAudio(String value) {
Boolean isAudioCommentaryEnabled = CrossPlatformProperties.getAudioCommentary();
String type = CrossPlatformProperties.getAudioCommentaryType();
if (isAudioCommentaryEnabled) {
if (type.equals(WATSON)) {
// playWatsonAudio(value);
} else if (type.equals(MARY)) {
playMaryAudio(value);
}
}
}
/**
* plays audio using marytts library
*
* @param value text value to play back
*/
public static void playMaryAudio(String value) {
try {
MaryInterface marytts = new LocalMaryInterface();
Set voices = marytts.getAvailableVoices();
String[] voiceList = voices.toArray(new String[voices.size()]);
marytts.setVoice(voiceList[0]);
// '!' results in playback being a bit faster, more natural
AudioInputStream audio = marytts.generateAudio(value + "!");
player = new marytts.util.data.audio.AudioPlayer(audio);
player.start();
player.join();
} catch (Exception e) {
e.getMessage();
}
}
/**
* watson audio
* Note: disabled watson as the library has not been updated since 2019
* @param value text value to play back
*/
/*
public synchronized static void playWatsonAudio(String value) {
TextToSpeech textToSpeech = new TextToSpeech();
// set username and password from IBM account
textToSpeech.setUsernameAndPassword("", "");
textToSpeech.setEndPoint("https://stream.watsonplatform.net/text-to-speech/api");
try {
SynthesizeOptions synthesizeOptions = new SynthesizeOptions.Builder().text(value).accept("audio/wav")
.voice("en-US_AllisonVoice").build();
InputStream inputStream = textToSpeech.synthesize(synthesizeOptions).execute();
InputStream in = WaveUtils.reWriteWaveHeader(inputStream);
AudioInputStream audio = AudioSystem.getAudioInputStream(new BufferedInputStream(in));
player = new marytts.util.data.audio.AudioPlayer(audio);
player.start();
player.join();
in.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
*/
/**
* logs to console if batch logging is enabled, Then logs are stored And printed
* to console once the test is complete
*
* @param priority priority of the message. eg. info, error, warn
* @param value string value to log
*/
private static void logConsoleMessage(Level priority, String value) {
if(Strings.isNullOrEmpty(value))
return;
if(Config.getBooleanValue(LOG_SKIP_CONSOLE))
return;
value = Helper.date.getTimestampSeconds() + " : " + getTestLogPrefix() + value;
value = Helper.stringRemoveLines(value);
// if batch logging is disabled, log to console
Boolean enableBatchLogging = CrossPlatformProperties.getEnableBatchLogging();
if (!enableBatchLogging) {
TestObject.getTestInfo().log.info(value);
}
// keep track of the logs
LogObject log = new LogObject(value, priority);
TestObject.getTestInfo().testLog.add(log);
}
/**
* sets the logging prefix
*
* @return the logging prefix
*/
private static String getTestLogPrefix() {
return TestObject.getTestInfo().className + "-" + TestObject.getTestInfo().testName + " - ";
}
private synchronized static ExtentTest getTestStep() {
return AbstractDriver.getStep().get();
}
/**
* prints out the entire test log for csv file at once Occurs When number of csv
* files are greater than 1
*/
public synchronized static void printBatchLogsToConsole() {
Boolean enableBatchLogging = CrossPlatformProperties.getEnableBatchLogging();
if (!enableBatchLogging)
return;
if (TestObject.getTestInfo().isTestComplete) {
// print before class logs
printBatchClassToConsole(TestObject.BEFORE_CLASS_PREFIX);
// print test logs
printLogs(TestObject.getTestInfo().testLogAll);
}
}
/**
* prints class level logs to console prints only once
*
* @param classType
*/
public static void printBatchClassToConsole(String classType) {
String testId = TestObject.getTestInfo().testFileClassName + classType;
printBatchToConsole(testId);
}
/**
* prints batch class to console based on testId
*
* @param testId
*/
public static void printBatchToConsole(String testId) {
// if batch login is disabled, return
if (!CrossPlatformProperties.getEnableBatchLogging())
return;
// if test class object does not exist, return
if (TestObject.testInfo.get(testId) == null)
return;
List logs = TestObject.getTestInfo(testId).testLog;
if(!logs.isEmpty())
printLogs(logs, testId);
}
/**
* prints current test logs
*
* @param logs list of log objects
*/
public static void printLogs(List logs) {
printLogs(logs, "");
}
/**
* prints logs to console removes logs from list after printing to console
*
* @param testLog list of logs
* @param testId id of the test
*/
public static void printLogs(List testLog, String testId) {
for (LogObject log : testLog) {
if (testId.isEmpty()) {
TestObject.getTestInfo().log.log(log.priority, log.value);
} else
TestObject.getTestInfo(testId).log.log(log.priority, log.value);
}
if (testId.isEmpty())
TestObject.getTestInfo().testLog = new ArrayList();
else
TestObject.getTestInfo(testId).testLog = new ArrayList();
}
public static void printLogoOnSuccess() {
if (!Config.getBooleanValue("console.printLogoOnSuccess"))
return;
System.out.println(
"\r\n" + " # \r\n" + " /## /## \r\n"
+ " #### # ###, \r\n" + "(######## ######## (######## \r\n"
+ "# *################### #\r\n" + "# ############### # ############### .#\r\n"
+ "# ############# ##### ############/ /#\r\n" + "# ########### ### .###.########## ##\r\n"
+ "#( ######### ### ### ######## # \r\n" + "## ###### ### .### ###### # \r\n"
+ " # ### #############.### #( \r\n" + " ## ### #################.### # \r\n"
+ " ## ## ##################### #( # \r\n" + " #( ######################### #. \r\n"
+ " #( ####################### #/ \r\n" + " ## #################### # \r\n"
+ " *# ################# ,# \r\n" + " ## ############# #. \r\n"
+ " #, ########* ## \r\n" + " ## .# #( \r\n"
+ " ,## ,## \r\n" + " ##, ");
}
/**
* compares autonomx latest version from maven central against current maven version.
* lets user know a new version of autonomx is available
* @throws XPathExpressionException
*/
public static boolean checkLatestAutonomxMavenVersion() {
try {
return checkLatestAutonomx();
}catch(Exception e) {
Config.putValue(TestLog.LOG_SKIP_CONSOLE, false, false);
System.out.println("Something has gone wrong with maven version check. error <: "+ e.getMessage() +"> To disable this message, set console.checkLatestAutonomx to false at report.property");
}catch(AssertionError e) {
Config.putValue(TestLog.LOG_SKIP_CONSOLE, false, false);
System.out.println("Something has gone wrong with maven version check. error <: "+ e.getMessage() +"> To disable this message, set console.checkLatestAutonomx to false at report.property");
}
return false;
}
/**
* compares autonomx latest version from maven central against current maven version.
* lets user know a new version of autonomx is available
* @throws XPathExpressionException
*/
public static boolean checkLatestAutonomx() {
if(!Config.getBooleanValue("console.checkLatestAutonomx"))
return false;
Config.putValue(TestLog.LOG_SKIP_CONSOLE, true, false);
// get autonomx maven version from maven central
ServiceObject service = new ServiceObject()
.withMethod("GET")
.withUriPath("https://mvnrepository.com/artifact/io.autonomx/autonomx-core/latest");
Response response = RestApiInterface.RestfullApiInterface(service);
//Response response = get("https://mvnrepository.com/artifact/io.autonomx/autonomx-core/latest");
if(response == null) return false;
String responseString = response.asString();
if(responseString.isEmpty()) return false;
// get autonomx version from maven central response
String version = StringUtils.EMPTY;
version = UtilityHelper.getValueBetweenStrings(responseString, "https://mvnrepository.com/artifact/io.autonomx/autonomx-core/", "/>", 1);
if(version.isEmpty()) return false;
String versionValue = Helper.stringNormalize(version);
// get current version
String autonomxCurrentVersionString = UtilityHelper.getMavenDependencyVersion("autonomxCore");
if(autonomxCurrentVersionString.isEmpty()) return false;
// compare versions
try {
ComparableVersion autonomxMavenCentral = new ComparableVersion(versionValue);
ComparableVersion localAutonomx = new ComparableVersion(autonomxCurrentVersionString);
if(autonomxMavenCentral.compareTo(localAutonomx) > 0) {
System.out.println("New version of Autonomx is available. current version: <" + autonomxCurrentVersionString + "> Latest version: <" + versionValue + "> Please consider updating to the latest version at the pom.xml file for the dependency: autonomxCore. Release notes at: https://github.com/autonomx/Autonomx/releases. To disable this message, set console.checkLatestAutonomx to false at report.property");
return true;
}
}catch(Exception e) {
e.getMessage();
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy