Skip to content

Commit

Permalink
Release 1.8-RC3
Browse files Browse the repository at this point in the history
Mostly improvements to the logging capabilities as described in https://medium.com/@mart.schneider/tweaking-your-ui-automation-logs-5620b051969b
  • Loading branch information
martinschneider committed Mar 31, 2020
1 parent 0515d9f commit bc90876
Show file tree
Hide file tree
Showing 34 changed files with 721 additions and 234 deletions.
2 changes: 1 addition & 1 deletion justtestlah-applitools/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<parent>
<groupId>qa.justtestlah</groupId>
<artifactId>justtestlah-parent</artifactId>
<version>1.8-RC2</version>
<version>1.8-RC3</version>
</parent>
<licenses>
<license>
Expand Down
2 changes: 1 addition & 1 deletion justtestlah-awsdevicefarm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<parent>
<groupId>qa.justtestlah</groupId>
<artifactId>justtestlah-parent</artifactId>
<version>1.8-RC2</version>
<version>1.8-RC3</version>
</parent>
<licenses>
<license>
Expand Down
2 changes: 1 addition & 1 deletion justtestlah-browserstack/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<parent>
<groupId>qa.justtestlah</groupId>
<artifactId>justtestlah-parent</artifactId>
<version>1.8-RC2</version>
<version>1.8-RC3</version>
</parent>
<licenses>
<license>
Expand Down
2 changes: 1 addition & 1 deletion justtestlah-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<parent>
<groupId>qa.justtestlah</groupId>
<artifactId>justtestlah-parent</artifactId>
<version>1.8-RC2</version>
<version>1.8-RC3</version>
</parent>
<licenses>
<license>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import qa.justtestlah.log.LogLevel;

/**
* Annotation to mark methods for which entry/exit logging should be enabled.
Expand All @@ -13,35 +14,18 @@
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EntryExitLogging {
/** OFF = no logging */
int OFF = -1;

/** TRACE level of logging. */
int TRACE = 0;

/** DEBUG level of logging. */
int DEBUG = 1;

/** INFO level of logging. */
int INFO = 2;

/** WARN level of logging. */
int WARN = 3;

/** ERROR level of logging. */
int ERROR = 4;

/**
* The log level for the entry exit log message.
*
* @return log level
*/
int entryExitLogLevel() default EntryExitLogging.DEBUG;
int entryExitLogLevel() default LogLevel.INFO;

/**
* The log level for the entry exit log message.
*
* @return log level
*/
int summaryLogLevel() default EntryExitLogging.INFO;
int summaryLogLevel() default LogLevel.OFF;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@EnableAspectJAutoProxy
public class AopConfig {

// placeholder for steps and page object packages
private static final String POINTCUT_TEMPLATE = "execution(public * __package__..*.*(..))";

@Value("${pages.package}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,52 @@
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import qa.justtestlah.annotations.EntryExitLogging;
import qa.justtestlah.log.LogLevel;
import qa.justtestlah.log.TestLogWriter;

/** Aspect to create SLF4J logging entries when entering and exiting a method. */
@Aspect
@Component
public class EntryExitLoggingAspect implements MethodInterceptor {

private static final Logger LOG = LoggerFactory.getLogger("entryExit");
@Autowired private TestLogWriter logWriter;

@Value("${entryexit.loglevel:DEBUG}")
@Value("${entryexit.loglevel:INFO}")
private String entryExitLogLevel;

@Value("${summary.loglevel:INFO}")
@Value("${summary.loglevel:OFF}")
private String summaryLogLevel;

@Around("@annotation(loggable)")
public Object logAnnotatedMethods(final ProceedingJoinPoint joinPoint, EntryExitLogging loggable)
throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
long start = entry(method, joinPoint.getArgs());
long start = entry(method, joinPoint.getArgs(), loggable.entryExitLogLevel());
Object returnValue = joinPoint.proceed();
long finish = System.currentTimeMillis();
exit(method, finish - start);
exit(method, finish - start, loggable.entryExitLogLevel(), loggable.summaryLogLevel());
return returnValue;
}

/** this is the entry point for advices configured in {@link qa.justtestlah.aop.AopConfig} */
public Object invoke(final MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
long start = entry(method, invocation.getArguments());
long start = entry(method, invocation.getArguments(), getLogLevel(entryExitLogLevel));
Object returnValue = invocation.proceed();
long finish = System.currentTimeMillis();
exit(method, finish - start);
exit(method, finish - start, getLogLevel(entryExitLogLevel), getLogLevel(summaryLogLevel));
return returnValue;
}

// log when entering a method
private long entry(Method method, Object[] methodArguments) {
StringBuilder logMessage = new StringBuilder("Entering ");
private long entry(Method method, Object[] methodArguments, int logLevel) {
StringBuilder logMessage = new StringBuilder();
logMessage.append("Entering ");
Class<?> clazz = method.getDeclaringClass();
logMessage.append(clazz.getSimpleName());
logMessage.append(":");
Expand All @@ -67,13 +69,14 @@ private long entry(Method method, Object[] methodArguments) {
}
logMessage.append("]");
}
logMessage(LOG, getLogLevel(entryExitLogLevel), logMessage.toString());
logWriter.log(logLevel, TestLogWriter.ENTRY_EXIT_INDENTATION, logMessage.toString());
return System.currentTimeMillis();
}

// log before exiting a method
private void exit(Method method, long duration) {
StringBuilder logMessage = new StringBuilder("Exiting ");
private void exit(Method method, long duration, int entryExitLogLevel, int summaryLogLevel) {
StringBuilder logMessage = new StringBuilder();
logMessage.append("Exiting ");
Class<?> clazz = method.getDeclaringClass();
logMessage.append(clazz.getSimpleName());
logMessage.append(":");
Expand All @@ -83,60 +86,36 @@ private void exit(Method method, long duration) {
logMessage.append(" ms");

// exit logging
logMessage(LOG, getLogLevel(entryExitLogLevel), logMessage.toString());
logWriter.log(entryExitLogLevel, TestLogWriter.ENTRY_EXIT_INDENTATION, logMessage.toString());

logMessage = new StringBuilder(clazz.getSimpleName());
logMessage = new StringBuilder();
logMessage.append(clazz.getSimpleName());
logMessage.append(":");
logMessage.append(method.getName());
logMessage.append(" took ");
logMessage.append(duration);
logMessage.append(" ms");

// summary logging
logMessage(LOG, getLogLevel(summaryLogLevel), logMessage.toString());
}

private void logMessage(Logger logger, int logLevel, String message) {
switch (logLevel) {
case EntryExitLogging.OFF:
break;
case EntryExitLogging.TRACE:
logger.trace(message);
break;
case EntryExitLogging.DEBUG:
logger.debug(message);
break;
case EntryExitLogging.INFO:
logger.info(message);
break;
case EntryExitLogging.WARN:
logger.warn(message);
break;
case EntryExitLogging.ERROR:
logger.error(message);
break;
default:
logger.debug(message);
break;
}
logWriter.log(summaryLogLevel, TestLogWriter.ENTRY_EXIT_INDENTATION, logMessage.toString());
}

private int getLogLevel(String parameter) {
switch (parameter.toLowerCase()) {
case "off":
return EntryExitLogging.OFF;
return LogLevel.OFF;
case "trace":
return EntryExitLogging.TRACE;
return LogLevel.TRACE;
case "debug":
return EntryExitLogging.DEBUG;
return LogLevel.DEBUG;
case "info":
return EntryExitLogging.INFO;
return LogLevel.INFO;
case "warn":
return EntryExitLogging.WARN;
return LogLevel.WARN;
case "error":
return EntryExitLogging.ERROR;
return LogLevel.ERROR;
default:
return EntryExitLogging.DEBUG;
return LogLevel.DEBUG;
}
}
}
24 changes: 19 additions & 5 deletions justtestlah-core/src/main/java/qa/justtestlah/base/BasePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import qa.justtestlah.locator.LocatorMap;
import qa.justtestlah.locator.LocatorParser;
import qa.justtestlah.locator.LocatorPlaceholders;
import qa.justtestlah.log.LogLevel;
import qa.justtestlah.log.TestLogWriter;
import qa.justtestlah.stubs.AppiumTemplateMatcher;
import qa.justtestlah.stubs.Applitools;
import qa.justtestlah.stubs.Galen;
Expand All @@ -34,6 +36,8 @@
/** Base class for page objects. */
public abstract class BasePage<T> extends Base {
protected static final Logger LOG = LoggerFactory.getLogger(BasePage.class);
protected static final Logger TESTLOG =
LoggerFactory.getLogger(TestLogWriter.TESTLOG_LOGGER_NAME);
protected static final int DEFAULT_VERIFICATION_TIMEOUT = 2000; // milliseconds
protected JustTestLahConfiguration configuration;
private LocatorMap locators;
Expand All @@ -46,10 +50,10 @@ public abstract class BasePage<T> extends Base {

@Autowired private Applitools applitools;

@Autowired private ImageUtils imageUtils;

@Autowired private Galen galen;

@Autowired private TestLogWriter logWriter;

protected LocatorMap getLocators() {
return locators;
}
Expand Down Expand Up @@ -154,7 +158,11 @@ private void loadLocators(String fileName) {
@SuppressWarnings("unchecked")
private T checkWindow() {
if (configuration.isEyesEnabled()) {
LOG.info("Eyes enabled, performing check on class {}", this.getClass().getSimpleName());
logWriter.log(
LogLevel.INFO,
TestLogWriter.WEBDRIVER_INDENTATION,
"Performing visual checks on class {}",
this.getClass().getSimpleName());
applitools.checkWindow();
} else {
LOG.debug(
Expand Down Expand Up @@ -220,7 +228,11 @@ public T verify(int timeout) {
// Galen
checkLayout();
Class<?> clazz = this.getClass();
LOG.info("Verifying screen identifiers for {}", clazz.getSimpleName());
logWriter.log(
LogLevel.INFO,
TestLogWriter.WEBDRIVER_INDENTATION,
"Verifying screen identifiers for {}",
clazz.getSimpleName());
while (clazz != Base.class) {
for (ScreenIdentifier identifiers : clazz.getAnnotationsByType(ScreenIdentifier.class)) {
for (String identifier : identifiers.value()) {
Expand All @@ -239,7 +251,9 @@ public T verify(int timeout) {
throw new ScreenVerificationException(
identifier, rawLocator, this.getClass().getSimpleName(), timeout);
}
LOG.info(
logWriter.log(
LogLevel.INFO,
TestLogWriter.WEBDRIVER_INDENTATION,
"[OK] {} is displayed {}:{}",
identifier,
rawLocator.getLeft(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import qa.justtestlah.exception.JustTestLahException;
import qa.justtestlah.log.CucumberLoggingPlugin;

/** Builds Cucumber options based on `justtestlah.properties` and sets them as System properties. */
public class CucumberOptionsBuilder {
Expand Down Expand Up @@ -35,7 +36,7 @@ private static void setCucumberProperty(String key, String value) {
}

private static String buildPluginProperty(PropertiesHolder properties) {
StringBuilder pluginProperty = new StringBuilder("pretty");
StringBuilder pluginProperty = new StringBuilder(CucumberLoggingPlugin.class.getName());
pluginProperty.append(DELIMITER);
pluginProperty.append("html:report");
pluginProperty.append(DELIMITER);
Expand Down
Loading

0 comments on commit bc90876

Please sign in to comment.