From 480037a29f34a1ea82ac8e5e5d0a833e1d8356a1 Mon Sep 17 00:00:00 2001 From: Iaroslav Iershov Date: Thu, 12 Jul 2018 12:06:26 +0300 Subject: [PATCH 1/5] #34: Provided basic changes - StepProcessor reworked --- .../reportportal/EnhancedMessage.java | 54 +++++++++++++++++ .../reportportal/StepProcessorsHolder.java | 23 +++++--- .../reportportal/StepsSetProfile.java | 54 ++++++++--------- .../github/invictum/reportportal/Utils.java | 6 +- .../reportportal/processor/ErrorLogger.java | 59 ------------------- .../reportportal/processor/FinishStep.java | 27 +++++++++ .../processor/FinishStepLogger.java | 22 ------- ...mlSourceAttacher.java => HtmlSources.java} | 23 ++++---- .../processor/ScreenshotAttacher.java | 44 -------------- ...iumLogsAttacher.java => SeleniumLogs.java} | 32 ++++++---- .../reportportal/processor/StartStep.java | 27 +++++++++ .../processor/StartStepLogger.java | 24 -------- .../processor/StepDataExtractor.java | 19 ++++++ .../reportportal/processor/StepError.java | 55 +++++++++++++++++ .../reportportal/processor/StepProcessor.java | 15 ----- .../processor/StepScreenshots.java | 49 +++++++++++++++ ....java => StepDataExtractorHolderTest.java} | 8 +-- .../reportportal/StepsSetProfileTest.java | 44 +++++++------- ...tepLoggerTest.java => FinishStepTest.java} | 6 +- ...AttacherTest.java => HtmlSourcesTest.java} | 6 +- ...StepLoggerTest.java => StartStepTest.java} | 6 +- ...rrorLoggerTest.java => StepErrorTest.java} | 14 ++--- ...cherTest.java => StepScreenshotsTest.java} | 6 +- 23 files changed, 352 insertions(+), 271 deletions(-) create mode 100644 src/main/java/com/github/invictum/reportportal/EnhancedMessage.java delete mode 100644 src/main/java/com/github/invictum/reportportal/processor/ErrorLogger.java create mode 100644 src/main/java/com/github/invictum/reportportal/processor/FinishStep.java delete mode 100644 src/main/java/com/github/invictum/reportportal/processor/FinishStepLogger.java rename src/main/java/com/github/invictum/reportportal/processor/{HtmlSourceAttacher.java => HtmlSources.java} (65%) delete mode 100644 src/main/java/com/github/invictum/reportportal/processor/ScreenshotAttacher.java rename src/main/java/com/github/invictum/reportportal/processor/{SeleniumLogsAttacher.java => SeleniumLogs.java} (53%) create mode 100644 src/main/java/com/github/invictum/reportportal/processor/StartStep.java delete mode 100644 src/main/java/com/github/invictum/reportportal/processor/StartStepLogger.java create mode 100644 src/main/java/com/github/invictum/reportportal/processor/StepDataExtractor.java create mode 100644 src/main/java/com/github/invictum/reportportal/processor/StepError.java delete mode 100644 src/main/java/com/github/invictum/reportportal/processor/StepProcessor.java create mode 100644 src/main/java/com/github/invictum/reportportal/processor/StepScreenshots.java rename src/test/java/com/github/invictum/reportportal/{StepProcessorHolderTest.java => StepDataExtractorHolderTest.java} (71%) rename src/test/java/com/github/invictum/reportportal/processor/{FinishStepLoggerTest.java => FinishStepTest.java} (87%) rename src/test/java/com/github/invictum/reportportal/processor/{HtmlSourceAttacherTest.java => HtmlSourcesTest.java} (74%) rename src/test/java/com/github/invictum/reportportal/processor/{StartStepLoggerTest.java => StartStepTest.java} (83%) rename src/test/java/com/github/invictum/reportportal/processor/{ErrorLoggerTest.java => StepErrorTest.java} (83%) rename src/test/java/com/github/invictum/reportportal/processor/{ScreenshotAttacherTest.java => StepScreenshotsTest.java} (74%) diff --git a/src/main/java/com/github/invictum/reportportal/EnhancedMessage.java b/src/main/java/com/github/invictum/reportportal/EnhancedMessage.java new file mode 100644 index 0000000..088c8ec --- /dev/null +++ b/src/main/java/com/github/invictum/reportportal/EnhancedMessage.java @@ -0,0 +1,54 @@ +package com.github.invictum.reportportal; + +import com.epam.reportportal.message.ReportPortalMessage; +import com.epam.reportportal.message.TypeAwareByteSource; +import rp.com.google.common.io.ByteSource; + +import java.io.File; +import java.io.IOException; +import java.util.Calendar; +import java.util.Date; + +/** + * Improved version of {@link ReportPortalMessage} that extended with details related to log level and date. + * Isolates all the date required to emit log message to Report Portal server. + */ +public class EnhancedMessage extends ReportPortalMessage { + + private LogLevel level = LogLevel.INFO; + private Date date = Calendar.getInstance().getTime(); + + public EnhancedMessage(String message) { + super(message); + } + + public EnhancedMessage(ByteSource data, String mediaType, String message) { + super(data, mediaType, message); + } + + public EnhancedMessage(TypeAwareByteSource data, String message) { + super(data, message); + } + + public EnhancedMessage(File file, String message) throws IOException { + super(file, message); + } + + public EnhancedMessage withLevel(LogLevel level) { + this.level = level; + return this; + } + + public EnhancedMessage withDate(Date date) { + this.date = date; + return this; + } + + public LogLevel getLevel() { + return level; + } + + public Date getDate() { + return date; + } +} diff --git a/src/main/java/com/github/invictum/reportportal/StepProcessorsHolder.java b/src/main/java/com/github/invictum/reportportal/StepProcessorsHolder.java index c2bc717..b1babad 100644 --- a/src/main/java/com/github/invictum/reportportal/StepProcessorsHolder.java +++ b/src/main/java/com/github/invictum/reportportal/StepProcessorsHolder.java @@ -1,25 +1,30 @@ package com.github.invictum.reportportal; -import com.github.invictum.reportportal.processor.StepProcessor; +import com.epam.reportportal.service.ReportPortal; +import com.github.invictum.reportportal.processor.StepDataExtractor; import net.thucydides.core.model.TestStep; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; /** - * Abstraction used to hold all registered step processors. - * Entry point to pass {@link TestStep} through sequence of ordered {@link StepProcessor} + * Hold all registered step extractors and proceed all passed {@link TestStep} + * Entry point to pass {@link TestStep} through sequence of {@link StepDataExtractor} */ public class StepProcessorsHolder { - private List processors = new ArrayList<>(); + private Set processors = new HashSet<>(); - public void register(StepProcessor... processors) { - this.processors = Arrays.asList(processors); + public void register(StepDataExtractor... processors) { + this.processors = new HashSet<>(Arrays.asList(processors)); } public void proceed(TestStep step) { - processors.forEach(processor -> processor.proceed(step)); + processors.forEach(processor -> { + Collection logs = processor.extract(step); + logs.forEach(item -> ReportPortal.emitLog(item, item.getLevel().toString(), item.getDate())); + }); } } diff --git a/src/main/java/com/github/invictum/reportportal/StepsSetProfile.java b/src/main/java/com/github/invictum/reportportal/StepsSetProfile.java index 232f7b8..5785fd0 100644 --- a/src/main/java/com/github/invictum/reportportal/StepsSetProfile.java +++ b/src/main/java/com/github/invictum/reportportal/StepsSetProfile.java @@ -3,8 +3,8 @@ import com.github.invictum.reportportal.processor.*; /** - * Describes @{@link StepProcessor} sets as a unions. - * It is possible to specify CUSTOM profile and register to it any @{@link StepProcessor}. Order of processor is matters. + * Describes @{@link StepDataExtractor} sets as a unions. + * It is possible to specify CUSTOM profile and register to it any @{@link StepDataExtractor}. Order of processor is matters. */ public enum StepsSetProfile { @@ -13,16 +13,16 @@ public enum StepsSetProfile { */ DEFAULT() { @Override - public StepProcessor[] processors() { - return new StepProcessor[]{ - new FinishStepLogger(), - new ScreenshotAttacher(), - new ErrorLogger() + public StepDataExtractor[] processors() { + return new StepDataExtractor[]{ + new FinishStep(), + new StepScreenshots(), + new StepError() }; } @Override - public StepsSetProfile registerProcessors(StepProcessor... steps) { + public StepsSetProfile registerProcessors(StepDataExtractor... steps) { throw new UnsupportedOperationException("Unable to register processors for DEFAULT profile"); } }, @@ -32,19 +32,19 @@ public StepsSetProfile registerProcessors(StepProcessor... steps) { */ FULL() { @Override - public StepProcessor[] processors() { - return new StepProcessor[]{ - new StartStepLogger(), - new ScreenshotAttacher(), - new FinishStepLogger(), - new ErrorLogger(), - new HtmlSourceAttacher(), - new SeleniumLogsAttacher() + public StepDataExtractor[] processors() { + return new StepDataExtractor[]{ + new StartStep(), + new StepScreenshots(), + new FinishStep(), + new StepError(), + new HtmlSources(), + new SeleniumLogs() }; } @Override - public StepsSetProfile registerProcessors(StepProcessor... steps) { + public StepsSetProfile registerProcessors(StepDataExtractor... steps) { throw new UnsupportedOperationException("Unable to register processors for FULL profile"); } }, @@ -54,15 +54,15 @@ public StepsSetProfile registerProcessors(StepProcessor... steps) { */ CUSTOM() { - private StepProcessor[] steps; + private StepDataExtractor[] steps; @Override - public StepProcessor[] processors() { + public StepDataExtractor[] processors() { return this.steps; } @Override - public StepsSetProfile registerProcessors(StepProcessor... steps) { + public StepsSetProfile registerProcessors(StepDataExtractor... steps) { this.steps = steps; return this; } @@ -73,15 +73,15 @@ public StepsSetProfile registerProcessors(StepProcessor... steps) { */ TREE_OPTIMIZED() { @Override - StepProcessor[] processors() { - return new StepProcessor[]{ - new ScreenshotAttacher(), - new ErrorLogger() + StepDataExtractor[] processors() { + return new StepDataExtractor[]{ + new StepScreenshots(), + new StepError() }; } @Override - public StepsSetProfile registerProcessors(StepProcessor... steps) { + public StepsSetProfile registerProcessors(StepDataExtractor... steps) { throw new UnsupportedOperationException("Unable to register processors for TREE_OPTIMIZED profile"); } }; @@ -91,7 +91,7 @@ public StepsSetProfile registerProcessors(StepProcessor... steps) { * * @return array of processors */ - abstract StepProcessor[] processors(); + abstract StepDataExtractor[] processors(); - public abstract StepsSetProfile registerProcessors(StepProcessor... steps); + public abstract StepsSetProfile registerProcessors(StepDataExtractor... steps); } diff --git a/src/main/java/com/github/invictum/reportportal/Utils.java b/src/main/java/com/github/invictum/reportportal/Utils.java index 8e4348d..7a0c141 100644 --- a/src/main/java/com/github/invictum/reportportal/Utils.java +++ b/src/main/java/com/github/invictum/reportportal/Utils.java @@ -15,10 +15,10 @@ public class Utils { * Defines log level based on step result status. * * @param testResult used to define log level - * @return log level as a {@link String} representation + * @return discovered log level */ - public static String logLevel(TestResult testResult) { - return Status.mapTo(testResult).logLevel().toString(); + public static LogLevel logLevel(TestResult testResult) { + return Status.mapTo(testResult).logLevel(); } /** diff --git a/src/main/java/com/github/invictum/reportportal/processor/ErrorLogger.java b/src/main/java/com/github/invictum/reportportal/processor/ErrorLogger.java deleted file mode 100644 index e45f8ea..0000000 --- a/src/main/java/com/github/invictum/reportportal/processor/ErrorLogger.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import com.epam.reportportal.service.ReportPortal; -import com.github.invictum.reportportal.Utils; -import net.thucydides.core.model.TestStep; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.function.Function; - -/** - * Emits log with error message if present - */ -public class ErrorLogger implements StepProcessor { - - private Function messageFormatter = step -> { - Throwable cause = step.getException().getOriginalCause(); - StringWriter writer = new StringWriter(); - cause.printStackTrace(new PrintWriter(writer)); - return writer.toString(); - }; - - @Deprecated - // Use constructor with function instead - public ErrorLogger(boolean fullLog) { - if (!fullLog) { - messageFormatter = TestStep::getConciseErrorMessage; - } - } - - /** - * Default constructor collects full stack trace - */ - public ErrorLogger() { - - } - - /** - * Constructor allows to pass custom function to format error message - * - * @param messageFormatter to use for message formatting - */ - public ErrorLogger(Function messageFormatter) { - this.messageFormatter = messageFormatter; - } - - @Override - public void proceed(final TestStep step) { - if (step.getException() != null) { - String errorMessage = messageFormatter.apply(step); - ReportPortal.emitLog(errorMessage, Utils.logLevel(step.getResult()), Utils.stepEndDate(step)); - } - } - - @Override - public boolean equals(Object obj) { - return obj instanceof ErrorLogger; - } -} diff --git a/src/main/java/com/github/invictum/reportportal/processor/FinishStep.java b/src/main/java/com/github/invictum/reportportal/processor/FinishStep.java new file mode 100644 index 0000000..382db12 --- /dev/null +++ b/src/main/java/com/github/invictum/reportportal/processor/FinishStep.java @@ -0,0 +1,27 @@ +package com.github.invictum.reportportal.processor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.Utils; +import net.thucydides.core.model.TestStep; + +import java.util.Collection; +import java.util.Collections; + +/** + * Extracts details about finished step + */ +public class FinishStep implements StepDataExtractor { + + @Override + public Collection extract(final TestStep step) { + String text = String.format("[%s] %s", step.getResult().name(), step.getDescription()); + EnhancedMessage message = new EnhancedMessage(text); + message.withDate(Utils.stepEndDate(step)).withLevel(Utils.logLevel(step.getResult())); + return Collections.singleton(message); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof FinishStep; + } +} diff --git a/src/main/java/com/github/invictum/reportportal/processor/FinishStepLogger.java b/src/main/java/com/github/invictum/reportportal/processor/FinishStepLogger.java deleted file mode 100644 index ea28b5d..0000000 --- a/src/main/java/com/github/invictum/reportportal/processor/FinishStepLogger.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import com.epam.reportportal.service.ReportPortal; -import com.github.invictum.reportportal.Utils; -import net.thucydides.core.model.TestStep; - -/** - * Emits details about finished step to Report Portal log facility. - */ -public class FinishStepLogger implements StepProcessor { - - @Override - public void proceed(final TestStep step) { - String message = String.format("[%s] %s", step.getResult().name(), step.getDescription()); - ReportPortal.emitLog(message, Utils.logLevel(step.getResult()), Utils.stepEndDate(step)); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof FinishStepLogger; - } -} diff --git a/src/main/java/com/github/invictum/reportportal/processor/HtmlSourceAttacher.java b/src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java similarity index 65% rename from src/main/java/com/github/invictum/reportportal/processor/HtmlSourceAttacher.java rename to src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java index 7613253..eb42a4c 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/HtmlSourceAttacher.java +++ b/src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java @@ -1,7 +1,6 @@ package com.github.invictum.reportportal.processor; -import com.epam.reportportal.message.ReportPortalMessage; -import com.epam.reportportal.service.ReportPortal; +import com.github.invictum.reportportal.EnhancedMessage; import com.github.invictum.reportportal.Utils; import net.thucydides.core.model.TestStep; import net.thucydides.core.screenshots.ScreenshotAndHtmlSource; @@ -10,18 +9,18 @@ import java.io.File; import java.io.IOException; -import java.util.Date; -import java.util.Optional; +import java.util.*; /** - * Attaches HTML sources to Report Portal log if present + * Extracts HTML sources, if present */ -public class HtmlSourceAttacher implements StepProcessor { +public class HtmlSources implements StepDataExtractor { - private final static Logger LOG = LoggerFactory.getLogger(HtmlSourceAttacher.class); + private final static Logger LOG = LoggerFactory.getLogger(HtmlSources.class); @Override - public void proceed(final TestStep step) { + public Collection extract(final TestStep step) { + Set sources = new HashSet<>(); if (!step.getScreenshots().isEmpty()) { Date stepStartTime = Date.from(step.getStartTime().toInstant()); for (ScreenshotAndHtmlSource screenshotAndHtmlSource : step.getScreenshots()) { @@ -30,18 +29,20 @@ public void proceed(final TestStep step) { Date timestamp = sourceFile.get().lastModified() < stepStartTime .getTime() ? stepStartTime : new Date(sourceFile.get().lastModified()); try { - ReportPortalMessage message = new ReportPortalMessage(sourceFile.get(), "HTML Source"); - ReportPortal.emitLog(message, Utils.logLevel(step.getResult()), timestamp); + EnhancedMessage message = new EnhancedMessage(sourceFile.get(), "Screenshot"); + message.withDate(timestamp).withLevel(Utils.logLevel(step.getResult())); + sources.add(message); } catch (IOException e) { LOG.error("Failed to attach sources"); } } } } + return sources; } @Override public boolean equals(Object obj) { - return obj instanceof HtmlSourceAttacher; + return obj instanceof HtmlSources; } } diff --git a/src/main/java/com/github/invictum/reportportal/processor/ScreenshotAttacher.java b/src/main/java/com/github/invictum/reportportal/processor/ScreenshotAttacher.java deleted file mode 100644 index 1c2ac74..0000000 --- a/src/main/java/com/github/invictum/reportportal/processor/ScreenshotAttacher.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import com.epam.reportportal.message.ReportPortalMessage; -import com.epam.reportportal.service.ReportPortal; -import com.github.invictum.reportportal.Utils; -import net.thucydides.core.model.TestStep; -import net.thucydides.core.screenshots.ScreenshotAndHtmlSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.util.Date; - -/** - * Attaches screenshots to Report Portal log if present - */ -public class ScreenshotAttacher implements StepProcessor { - - private final static Logger LOG = LoggerFactory.getLogger(ScreenshotAttacher.class); - - @Override - public void proceed(final TestStep step) { - if (!step.getScreenshots().isEmpty()) { - Date stepStartTime = Date.from(step.getStartTime().toInstant()); - for (ScreenshotAndHtmlSource screenshotAndHtmlSource : step.getScreenshots()) { - File screenshotFile = screenshotAndHtmlSource.getScreenshot(); - Date timestamp = screenshotFile.lastModified() < stepStartTime - .getTime() ? stepStartTime : new Date(screenshotFile.lastModified()); - try { - ReportPortalMessage message = new ReportPortalMessage(screenshotFile, "Screenshot"); - ReportPortal.emitLog(message, Utils.logLevel(step.getResult()), timestamp); - } catch (IOException e) { - LOG.error("Failed to attach screenshot"); - } - } - } - } - - @Override - public boolean equals(Object obj) { - return obj instanceof ScreenshotAttacher; - } -} diff --git a/src/main/java/com/github/invictum/reportportal/processor/SeleniumLogsAttacher.java b/src/main/java/com/github/invictum/reportportal/processor/SeleniumLogs.java similarity index 53% rename from src/main/java/com/github/invictum/reportportal/processor/SeleniumLogsAttacher.java rename to src/main/java/com/github/invictum/reportportal/processor/SeleniumLogs.java index aedb2ac..c9c62d6 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/SeleniumLogsAttacher.java +++ b/src/main/java/com/github/invictum/reportportal/processor/SeleniumLogs.java @@ -1,45 +1,53 @@ package com.github.invictum.reportportal.processor; -import com.epam.reportportal.service.ReportPortal; -import com.github.invictum.reportportal.EnhancedLogEntry; -import com.github.invictum.reportportal.LogLevel; -import com.github.invictum.reportportal.LogStorage; -import com.github.invictum.reportportal.Utils; +import com.github.invictum.reportportal.*; import com.github.invictum.reportportal.injector.IntegrationInjector; import net.thucydides.core.model.TestStep; +import java.util.Collection; import java.util.Date; +import java.util.HashSet; +import java.util.Set; import java.util.function.Predicate; /** - * Attaches logs provided by Selenium + * Extracts logs provided by Selenium, if possible */ -public class SeleniumLogsAttacher implements StepProcessor { +public class SeleniumLogs implements StepDataExtractor { private Predicate filter; - public SeleniumLogsAttacher(Predicate filter) { + /** + * Pre-filter only logs that matches predicate + */ + public SeleniumLogs(Predicate filter) { this.filter = filter; } - public SeleniumLogsAttacher() { + /** + * Extracts all available logs + */ + public SeleniumLogs() { this(log -> true); } @Override - public void proceed(final TestStep step) { + public Collection extract(final TestStep step) { long start = Utils.stepEndDate(step).getTime(); long end = Utils.stepEndDate(step).getTime(); LogStorage storage = IntegrationInjector.getInjector().getInstance(LogStorage.class); + Set logs = new HashSet<>(); storage.query(filter.and(entry -> start <= entry.getTimestamp() && entry.getTimestamp() >= end)) .forEach(log -> { String message = String.format("[Selenium-%s] [%s] %s", log.getType(), log.getLevel(), log.getMessage()); - ReportPortal.emitLog(message, LogLevel.DEBUG.toString(), new Date(log.getTimestamp())); + EnhancedMessage entry = new EnhancedMessage(message).withLevel(LogLevel.DEBUG).withDate(new Date(log.getTimestamp())); + logs.add(entry); }); + return logs; } @Override public boolean equals(Object obj) { - return obj instanceof SeleniumLogsAttacher; + return obj instanceof SeleniumLogs; } } diff --git a/src/main/java/com/github/invictum/reportportal/processor/StartStep.java b/src/main/java/com/github/invictum/reportportal/processor/StartStep.java new file mode 100644 index 0000000..1c65b2c --- /dev/null +++ b/src/main/java/com/github/invictum/reportportal/processor/StartStep.java @@ -0,0 +1,27 @@ +package com.github.invictum.reportportal.processor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.Utils; +import net.thucydides.core.model.TestStep; + +import java.util.Collection; +import java.util.Collections; +import java.util.Date; + +/** + * Extracts data about started step + */ +public class StartStep implements StepDataExtractor { + + @Override + public Collection extract(final TestStep step) { + Date startDate = Utils.stepStartDate(step); + EnhancedMessage message = new EnhancedMessage("[STARTED] " + step.getDescription()); + return Collections.singleton(message.withDate(startDate).withLevel(Utils.logLevel(step.getResult()))); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof StartStep; + } +} diff --git a/src/main/java/com/github/invictum/reportportal/processor/StartStepLogger.java b/src/main/java/com/github/invictum/reportportal/processor/StartStepLogger.java deleted file mode 100644 index 6613546..0000000 --- a/src/main/java/com/github/invictum/reportportal/processor/StartStepLogger.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import com.epam.reportportal.service.ReportPortal; -import com.github.invictum.reportportal.Utils; -import net.thucydides.core.model.TestStep; - -import java.util.Date; - -/** - * Emits new log for Report Portal for each started step - */ -public class StartStepLogger implements StepProcessor { - - @Override - public void proceed(final TestStep step) { - Date startDate = Utils.stepStartDate(step); - ReportPortal.emitLog("[STARTED] " + step.getDescription(), Utils.logLevel(step.getResult()), startDate); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof StartStepLogger; - } -} diff --git a/src/main/java/com/github/invictum/reportportal/processor/StepDataExtractor.java b/src/main/java/com/github/invictum/reportportal/processor/StepDataExtractor.java new file mode 100644 index 0000000..37c4c0b --- /dev/null +++ b/src/main/java/com/github/invictum/reportportal/processor/StepDataExtractor.java @@ -0,0 +1,19 @@ +package com.github.invictum.reportportal.processor; + +import com.github.invictum.reportportal.EnhancedMessage; +import net.thucydides.core.model.TestStep; + +import java.util.Collection; + +/** + * Single unit of sequence used to extract a set of {@link EnhancedMessage} from {@link TestStep}. + */ +public interface StepDataExtractor { + /** + * Method invoked to extract data from {@link TestStep} + * + * @param step used to extract data + * @return step data represented as collection of {@link EnhancedMessage}. If extractor is unable to find any suitable data empty collection should be returned + */ + Collection extract(final TestStep step); +} diff --git a/src/main/java/com/github/invictum/reportportal/processor/StepError.java b/src/main/java/com/github/invictum/reportportal/processor/StepError.java new file mode 100644 index 0000000..5e567f2 --- /dev/null +++ b/src/main/java/com/github/invictum/reportportal/processor/StepError.java @@ -0,0 +1,55 @@ +package com.github.invictum.reportportal.processor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.Utils; +import net.thucydides.core.model.TestStep; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Collection; +import java.util.Collections; +import java.util.function.Function; + +/** + * Extracts error if present + */ +public class StepError implements StepDataExtractor { + + private Function messageFormatter; + + /** + * Default constructor collects full stack trace + */ + public StepError() { + this(step -> { + Throwable cause = step.getException().getOriginalCause(); + StringWriter writer = new StringWriter(); + cause.printStackTrace(new PrintWriter(writer)); + return writer.toString(); + }); + } + + /** + * Constructor allows to pass custom function to format error message + * + * @param messageFormatter to use for message formatting + */ + public StepError(Function messageFormatter) { + this.messageFormatter = messageFormatter; + } + + @Override + public Collection extract(final TestStep step) { + if (step.getException() != null) { + EnhancedMessage message = new EnhancedMessage(messageFormatter.apply(step)); + message.withLevel(Utils.logLevel(step.getResult())).withDate(Utils.stepEndDate(step)); + return Collections.singleton(message); + } + return Collections.emptySet(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof StepError; + } +} diff --git a/src/main/java/com/github/invictum/reportportal/processor/StepProcessor.java b/src/main/java/com/github/invictum/reportportal/processor/StepProcessor.java deleted file mode 100644 index a7e0f66..0000000 --- a/src/main/java/com/github/invictum/reportportal/processor/StepProcessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import net.thucydides.core.model.TestStep; - -/** - * Single unit of sequence used to proceed @{@link TestStep}. Each @{@link TestStep} is invoked by registered processors. - */ -public interface StepProcessor { - /** - * Method invoked to proceed @{@link TestStep} details - * - * @param step to proceed - */ - void proceed(final TestStep step); -} diff --git a/src/main/java/com/github/invictum/reportportal/processor/StepScreenshots.java b/src/main/java/com/github/invictum/reportportal/processor/StepScreenshots.java new file mode 100644 index 0000000..6dde6e1 --- /dev/null +++ b/src/main/java/com/github/invictum/reportportal/processor/StepScreenshots.java @@ -0,0 +1,49 @@ +package com.github.invictum.reportportal.processor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.Utils; +import net.thucydides.core.model.TestStep; +import net.thucydides.core.screenshots.ScreenshotAndHtmlSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +/** + * Extracts screenshots from {@link TestStep}, if present + */ +public class StepScreenshots implements StepDataExtractor { + + private final static Logger LOG = LoggerFactory.getLogger(StepScreenshots.class); + + @Override + public Collection extract(final TestStep step) { + Set messages = new HashSet<>(); + if (!step.getScreenshots().isEmpty()) { + Date stepStartTime = Date.from(step.getStartTime().toInstant()); + for (ScreenshotAndHtmlSource screenshotAndHtmlSource : step.getScreenshots()) { + File screenshotFile = screenshotAndHtmlSource.getScreenshot(); + Date timestamp = screenshotFile.lastModified() < stepStartTime.getTime() ? + stepStartTime : new Date(screenshotFile.lastModified()); + try { + EnhancedMessage message = new EnhancedMessage(screenshotFile, "Screenshot"); + message.withDate(timestamp).withLevel(Utils.logLevel(step.getResult())); + messages.add(message); + } catch (IOException e) { + LOG.error("Unable to attach screenshot"); + } + } + } + return messages; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof StepScreenshots; + } +} diff --git a/src/test/java/com/github/invictum/reportportal/StepProcessorHolderTest.java b/src/test/java/com/github/invictum/reportportal/StepDataExtractorHolderTest.java similarity index 71% rename from src/test/java/com/github/invictum/reportportal/StepProcessorHolderTest.java rename to src/test/java/com/github/invictum/reportportal/StepDataExtractorHolderTest.java index 9da0b95..e3918dd 100644 --- a/src/test/java/com/github/invictum/reportportal/StepProcessorHolderTest.java +++ b/src/test/java/com/github/invictum/reportportal/StepDataExtractorHolderTest.java @@ -1,6 +1,6 @@ package com.github.invictum.reportportal; -import com.github.invictum.reportportal.processor.StartStepLogger; +import com.github.invictum.reportportal.processor.StartStep; import net.thucydides.core.model.TestStep; import org.junit.Test; import org.junit.runner.RunWith; @@ -9,10 +9,10 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.StrictStubs.class) -public class StepProcessorHolderTest { +public class StepDataExtractorHolderTest { @Mock - private StartStepLogger processorMock; + private StartStep processorMock; @Test public void proceedTest() { @@ -20,6 +20,6 @@ public void proceedTest() { holder.register(processorMock); TestStep step = new TestStep(); holder.proceed(step); - Mockito.verify(processorMock, Mockito.times(1)).proceed(step); + Mockito.verify(processorMock, Mockito.times(1)).extract(step); } } diff --git a/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java b/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java index ebd0f41..3d741de 100644 --- a/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java +++ b/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java @@ -11,58 +11,58 @@ public class StepsSetProfileTest { @Test public void fullProfile() { - StepProcessor[] actual = StepsSetProfile.FULL.processors(); - StepProcessor[] expected = new StepProcessor[]{ - new StartStepLogger(), - new ScreenshotAttacher(), - new FinishStepLogger(), - new ErrorLogger(true), - new HtmlSourceAttacher(), - new SeleniumLogsAttacher() + StepDataExtractor[] actual = StepsSetProfile.FULL.processors(); + StepDataExtractor[] expected = new StepDataExtractor[]{ + new StartStep(), + new StepScreenshots(), + new FinishStep(), + new StepError(), + new HtmlSources(), + new SeleniumLogs() }; Assert.assertArrayEquals(actual, expected); } @Test(expected = UnsupportedOperationException.class) public void fullProfileCustomization() { - StepsSetProfile.FULL.registerProcessors(new ScreenshotAttacher()); + StepsSetProfile.FULL.registerProcessors(new StepScreenshots()); } @Test public void defaultProfile() { - StepProcessor[] actual = StepsSetProfile.DEFAULT.processors(); - StepProcessor[] expected = new StepProcessor[]{ - new FinishStepLogger(), - new ScreenshotAttacher(), - new ErrorLogger(true) + StepDataExtractor[] actual = StepsSetProfile.DEFAULT.processors(); + StepDataExtractor[] expected = new StepDataExtractor[]{ + new FinishStep(), + new StepScreenshots(), + new StepError() }; Assert.assertArrayEquals(actual, expected); } @Test(expected = UnsupportedOperationException.class) public void defaultProfileCustomization() { - StepsSetProfile.DEFAULT.registerProcessors(new ScreenshotAttacher()); + StepsSetProfile.DEFAULT.registerProcessors(new StepScreenshots()); } @Test public void customProfileCustomization() { - StepsSetProfile profile = StepsSetProfile.CUSTOM.registerProcessors(new ScreenshotAttacher()); - StepProcessor[] expected = new StepProcessor[]{new ScreenshotAttacher()}; + StepsSetProfile profile = StepsSetProfile.CUSTOM.registerProcessors(new StepScreenshots()); + StepDataExtractor[] expected = new StepDataExtractor[]{new StepScreenshots()}; Assert.assertArrayEquals(profile.processors(), expected); } @Test public void treeOptimizedProfile() { - StepProcessor[] actual = StepsSetProfile.TREE_OPTIMIZED.processors(); - StepProcessor[] expected = new StepProcessor[]{ - new ScreenshotAttacher(), - new ErrorLogger(true) + StepDataExtractor[] actual = StepsSetProfile.TREE_OPTIMIZED.processors(); + StepDataExtractor[] expected = new StepDataExtractor[]{ + new StepScreenshots(), + new StepError() }; Assert.assertArrayEquals(actual, expected); } @Test(expected = UnsupportedOperationException.class) public void treeOptimizedProfileCustomization() { - StepsSetProfile.TREE_OPTIMIZED.registerProcessors(new HtmlSourceAttacher()); + StepsSetProfile.TREE_OPTIMIZED.registerProcessors(new HtmlSources()); } } diff --git a/src/test/java/com/github/invictum/reportportal/processor/FinishStepLoggerTest.java b/src/test/java/com/github/invictum/reportportal/processor/FinishStepTest.java similarity index 87% rename from src/test/java/com/github/invictum/reportportal/processor/FinishStepLoggerTest.java rename to src/test/java/com/github/invictum/reportportal/processor/FinishStepTest.java index 8584896..5fc2238 100644 --- a/src/test/java/com/github/invictum/reportportal/processor/FinishStepLoggerTest.java +++ b/src/test/java/com/github/invictum/reportportal/processor/FinishStepTest.java @@ -11,19 +11,19 @@ import java.time.ZonedDateTime; @RunWith(MockitoJUnitRunner.StrictStubs.class) -public class FinishStepLoggerTest { +public class FinishStepTest { @Mock private TestStep stepMock; @Test public void finishStepLoggerTest() { - FinishStepLogger finishStepLogger = new FinishStepLogger(); + FinishStep finishStep = new FinishStep(); /* Setup mock */ Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); Mockito.when(stepMock.getResult()).thenReturn(TestResult.SUCCESS); Mockito.when(stepMock.getDuration()).thenReturn(1000L); - finishStepLogger.proceed(stepMock); + finishStep.extract(stepMock); /* Verification */ Mockito.verify(stepMock, Mockito.times(1)).getStartTime(); Mockito.verify(stepMock, Mockito.times(1)).getDescription(); diff --git a/src/test/java/com/github/invictum/reportportal/processor/HtmlSourceAttacherTest.java b/src/test/java/com/github/invictum/reportportal/processor/HtmlSourcesTest.java similarity index 74% rename from src/test/java/com/github/invictum/reportportal/processor/HtmlSourceAttacherTest.java rename to src/test/java/com/github/invictum/reportportal/processor/HtmlSourcesTest.java index 1707a45..bb66f31 100644 --- a/src/test/java/com/github/invictum/reportportal/processor/HtmlSourceAttacherTest.java +++ b/src/test/java/com/github/invictum/reportportal/processor/HtmlSourcesTest.java @@ -8,15 +8,15 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.StrictStubs.class) -public class HtmlSourceAttacherTest { +public class HtmlSourcesTest { @Mock private TestStep stepMock; @Test public void noScreenshotsTest() { - HtmlSourceAttacher htmlSourceAttacher = new HtmlSourceAttacher(); - htmlSourceAttacher.proceed(stepMock); + HtmlSources htmlSources = new HtmlSources(); + htmlSources.extract(stepMock); Mockito.verify(stepMock, Mockito.never()).getResult(); } } diff --git a/src/test/java/com/github/invictum/reportportal/processor/StartStepLoggerTest.java b/src/test/java/com/github/invictum/reportportal/processor/StartStepTest.java similarity index 83% rename from src/test/java/com/github/invictum/reportportal/processor/StartStepLoggerTest.java rename to src/test/java/com/github/invictum/reportportal/processor/StartStepTest.java index 54d63db..6c163af 100644 --- a/src/test/java/com/github/invictum/reportportal/processor/StartStepLoggerTest.java +++ b/src/test/java/com/github/invictum/reportportal/processor/StartStepTest.java @@ -10,17 +10,17 @@ import java.time.ZonedDateTime; @RunWith(MockitoJUnitRunner.StrictStubs.class) -public class StartStepLoggerTest { +public class StartStepTest { @Mock private TestStep stepMock; @Test public void startStepLoggerTest() { - StartStepLogger startStepLogger = new StartStepLogger(); + StartStep startStep = new StartStep(); /* Setup mock */ Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); - startStepLogger.proceed(stepMock); + startStep.extract(stepMock); Mockito.verify(stepMock, Mockito.times(1)).getStartTime(); Mockito.verify(stepMock, Mockito.times(1)).getDescription(); Mockito.verify(stepMock, Mockito.times(1)).getResult(); diff --git a/src/test/java/com/github/invictum/reportportal/processor/ErrorLoggerTest.java b/src/test/java/com/github/invictum/reportportal/processor/StepErrorTest.java similarity index 83% rename from src/test/java/com/github/invictum/reportportal/processor/ErrorLoggerTest.java rename to src/test/java/com/github/invictum/reportportal/processor/StepErrorTest.java index c6c4678..3331008 100644 --- a/src/test/java/com/github/invictum/reportportal/processor/ErrorLoggerTest.java +++ b/src/test/java/com/github/invictum/reportportal/processor/StepErrorTest.java @@ -11,7 +11,7 @@ import java.time.ZonedDateTime; @RunWith(MockitoJUnitRunner.StrictStubs.class) -public class ErrorLoggerTest { +public class StepErrorTest { @Mock private TestStep stepMock; @@ -21,19 +21,19 @@ public class ErrorLoggerTest { @Test public void noExceptionTest() { - ErrorLogger errorLogger = new ErrorLogger(); - errorLogger.proceed(stepMock); + StepError stepError = new StepError(); + stepError.extract(stepMock); Mockito.verify(stepMock, Mockito.times(1)).getException(); Mockito.verify(stepMock, Mockito.never()).getConciseErrorMessage(); } @Test public void customFormatExceptionLogTest() { - ErrorLogger errorLogger = new ErrorLogger(TestStep::getConciseErrorMessage); + StepError stepError = new StepError(TestStep::getConciseErrorMessage); /* Setup mock */ Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); Mockito.when(stepMock.getException()).thenReturn(failureCauseMock); - errorLogger.proceed(stepMock); + stepError.extract(stepMock); /* Verification */ Mockito.verify(stepMock, Mockito.times(1)).getException(); Mockito.verify(stepMock, Mockito.times(1)).getConciseErrorMessage(); @@ -42,12 +42,12 @@ public void customFormatExceptionLogTest() { @Test public void fullExceptionLogTest() { - ErrorLogger errorLogger = new ErrorLogger(); + StepError stepError = new StepError(); /* Setup mock */ Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); Mockito.when(stepMock.getException()).thenReturn(failureCauseMock); Mockito.when(failureCauseMock.getOriginalCause()).thenReturn(new IllegalStateException("Details")); - errorLogger.proceed(stepMock); + stepError.extract(stepMock); /* Verification */ Mockito.verify(stepMock, Mockito.times(2)).getException(); Mockito.verify(stepMock, Mockito.times(1)).getResult(); diff --git a/src/test/java/com/github/invictum/reportportal/processor/ScreenshotAttacherTest.java b/src/test/java/com/github/invictum/reportportal/processor/StepScreenshotsTest.java similarity index 74% rename from src/test/java/com/github/invictum/reportportal/processor/ScreenshotAttacherTest.java rename to src/test/java/com/github/invictum/reportportal/processor/StepScreenshotsTest.java index cfd101c..77e47d5 100644 --- a/src/test/java/com/github/invictum/reportportal/processor/ScreenshotAttacherTest.java +++ b/src/test/java/com/github/invictum/reportportal/processor/StepScreenshotsTest.java @@ -8,15 +8,15 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.StrictStubs.class) -public class ScreenshotAttacherTest { +public class StepScreenshotsTest { @Mock private TestStep stepMock; @Test public void noScreenshotsTest() { - ScreenshotAttacher screenshotAttacher = new ScreenshotAttacher(); - screenshotAttacher.proceed(stepMock); + StepScreenshots stepScreenshots = new StepScreenshots(); + stepScreenshots.extract(stepMock); Mockito.verify(stepMock, Mockito.never()).getResult(); } } From 22683dd880c1c166bc96372cf68923e1afbe290a Mon Sep 17 00:00:00 2001 From: Iaroslav Iershov Date: Thu, 12 Jul 2018 12:15:31 +0300 Subject: [PATCH 2/5] #34: Resolve merge conflicts --- .../invictum/reportportal/processor/HtmlSources.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java b/src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java index 44d210b..ce96b04 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java +++ b/src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java @@ -1,14 +1,12 @@ package com.github.invictum.reportportal.processor; -import com.epam.reportportal.message.ReportPortalMessage; -import com.epam.reportportal.service.ReportPortal; import com.github.invictum.reportportal.EnhancedMessage; import com.github.invictum.reportportal.Utils; -import com.google.common.io.ByteSource; import net.thucydides.core.model.TestStep; import net.thucydides.core.screenshots.ScreenshotAndHtmlSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import rp.com.google.common.io.ByteSource; import java.io.File; import java.io.IOException; @@ -20,7 +18,7 @@ */ public class HtmlSources implements StepDataExtractor { - private final static String MIME = "test/plain"; + private final static String MIME = "text/plain"; private final static Logger LOG = LoggerFactory.getLogger(HtmlSources.class); @Override @@ -36,8 +34,6 @@ public Collection extract(final TestStep step) { try { byte[] data = Files.readAllBytes(sourceFile.get().toPath()); EnhancedMessage message = new EnhancedMessage(ByteSource.wrap(data), MIME, "HTML Source"); - ReportPortal.emitLog(message, Utils.logLevel(step.getResult()), timestamp); - EnhancedMessage message = new EnhancedMessage(sourceFile.get(), "Screenshot"); message.withDate(timestamp).withLevel(Utils.logLevel(step.getResult())); sources.add(message); } catch (IOException e) { @@ -46,6 +42,7 @@ public Collection extract(final TestStep step) { } } } + return sources; } @Override From c3bed1ef344c0c5cbbd762982772118368e510f1 Mon Sep 17 00:00:00 2001 From: Iaroslav Iershov Date: Fri, 13 Jul 2018 14:48:43 +0300 Subject: [PATCH 3/5] #34: Updated unit tests for extractors --- README.md | 4 +- ...der.java => StepDataExtractorsHolder.java} | 8 +-- .../StepProcessorsHolderProvider.java | 6 +- .../reportportal/StepsSetProfile.java | 4 +- .../{processor => extractor}/FinishStep.java | 2 +- .../{processor => extractor}/HtmlSources.java | 2 +- .../SeleniumLogs.java | 2 +- .../{processor => extractor}/StartStep.java | 2 +- .../StepDataExtractor.java | 2 +- .../{processor => extractor}/StepError.java | 2 +- .../StepScreenshots.java | 2 +- .../reportportal/handler/FlatHandler.java | 2 +- .../injector/SerenityPortalModule.java | 4 +- .../StepDataExtractorHolderTest.java | 25 -------- .../StepDataExtractorsHolderTest.java | 29 +++++++++ .../reportportal/StepsSetProfileTest.java | 2 +- .../reportportal/UtilsLogLevelTest.java | 19 +++--- .../extractor/FinishStepTest.java | 54 ++++++++++++++++ .../extractor/HtmlSourcesTest.java | 53 ++++++++++++++++ .../reportportal/extractor/StartStepTest.java | 37 +++++++++++ .../reportportal/extractor/StepErrorTest.java | 61 +++++++++++++++++++ .../extractor/StepScreenshotsTest.java | 52 ++++++++++++++++ .../processor/FinishStepTest.java | 33 ---------- .../processor/HtmlSourcesTest.java | 22 ------- .../reportportal/processor/StartStepTest.java | 28 --------- .../reportportal/processor/StepErrorTest.java | 55 ----------------- .../processor/StepScreenshotsTest.java | 22 ------- 27 files changed, 317 insertions(+), 217 deletions(-) rename src/main/java/com/github/invictum/reportportal/{StepProcessorsHolder.java => StepDataExtractorsHolder.java} (86%) rename src/main/java/com/github/invictum/reportportal/{processor => extractor}/FinishStep.java (93%) rename src/main/java/com/github/invictum/reportportal/{processor => extractor}/HtmlSources.java (97%) rename src/main/java/com/github/invictum/reportportal/{processor => extractor}/SeleniumLogs.java (96%) rename src/main/java/com/github/invictum/reportportal/{processor => extractor}/StartStep.java (93%) rename src/main/java/com/github/invictum/reportportal/{processor => extractor}/StepDataExtractor.java (92%) rename src/main/java/com/github/invictum/reportportal/{processor => extractor}/StepError.java (96%) rename src/main/java/com/github/invictum/reportportal/{processor => extractor}/StepScreenshots.java (97%) delete mode 100644 src/test/java/com/github/invictum/reportportal/StepDataExtractorHolderTest.java create mode 100644 src/test/java/com/github/invictum/reportportal/StepDataExtractorsHolderTest.java create mode 100644 src/test/java/com/github/invictum/reportportal/extractor/FinishStepTest.java create mode 100644 src/test/java/com/github/invictum/reportportal/extractor/HtmlSourcesTest.java create mode 100644 src/test/java/com/github/invictum/reportportal/extractor/StartStepTest.java create mode 100644 src/test/java/com/github/invictum/reportportal/extractor/StepErrorTest.java create mode 100644 src/test/java/com/github/invictum/reportportal/extractor/StepScreenshotsTest.java delete mode 100644 src/test/java/com/github/invictum/reportportal/processor/FinishStepTest.java delete mode 100644 src/test/java/com/github/invictum/reportportal/processor/HtmlSourcesTest.java delete mode 100644 src/test/java/com/github/invictum/reportportal/processor/StartStepTest.java delete mode 100644 src/test/java/com/github/invictum/reportportal/processor/StepErrorTest.java delete mode 100644 src/test/java/com/github/invictum/reportportal/processor/StepScreenshotsTest.java diff --git a/README.md b/README.md index 603ffea..eeaa8f1 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ ReportIntegrationConfig.get().useProfile(profile); **Processors** -All step processors available out of the box may be observed in `com.github.invictum.reportportal.processor` package. +All step processors available out of the box may be observed in `com.github.invictum.reportportal.extractor` package. For now following processors are available: - `StartStepLogger` logs all started steps. - `FinishStepLogger` logs all finished steps. Log level depends on step results. @@ -135,7 +135,7 @@ SeleniumLogsAttacher logsAttacher = new SeleniumLogsAttacher(log -> log.getType( profile.registerProcessors(errorLogger); ``` -It is possible to use integrated processors as well as implemented by your own. To make own processor implement `StepProcessor` interface. In custom implementation access to Serenity's `TestStep` object is provided +It is possible to use integrated processors as well as implemented by your own. To make own extractor implement `StepProcessor` interface. In custom implementation access to Serenity's `TestStep` object is provided ``` public class MyCustomLoggerLogger implements StepProcessor { diff --git a/src/main/java/com/github/invictum/reportportal/StepProcessorsHolder.java b/src/main/java/com/github/invictum/reportportal/StepDataExtractorsHolder.java similarity index 86% rename from src/main/java/com/github/invictum/reportportal/StepProcessorsHolder.java rename to src/main/java/com/github/invictum/reportportal/StepDataExtractorsHolder.java index b1babad..a33c64e 100644 --- a/src/main/java/com/github/invictum/reportportal/StepProcessorsHolder.java +++ b/src/main/java/com/github/invictum/reportportal/StepDataExtractorsHolder.java @@ -1,7 +1,7 @@ package com.github.invictum.reportportal; import com.epam.reportportal.service.ReportPortal; -import com.github.invictum.reportportal.processor.StepDataExtractor; +import com.github.invictum.reportportal.extractor.StepDataExtractor; import net.thucydides.core.model.TestStep; import java.util.Arrays; @@ -10,10 +10,10 @@ import java.util.Set; /** - * Hold all registered step extractors and proceed all passed {@link TestStep} + * Hold all registered step extractors and proceed all passed {@link TestStep} objects * Entry point to pass {@link TestStep} through sequence of {@link StepDataExtractor} */ -public class StepProcessorsHolder { +public class StepDataExtractorsHolder { private Set processors = new HashSet<>(); @@ -23,7 +23,7 @@ public void register(StepDataExtractor... processors) { public void proceed(TestStep step) { processors.forEach(processor -> { - Collection logs = processor.extract(step); + Collection logs = processor.extract(step.clone()); logs.forEach(item -> ReportPortal.emitLog(item, item.getLevel().toString(), item.getDate())); }); } diff --git a/src/main/java/com/github/invictum/reportportal/StepProcessorsHolderProvider.java b/src/main/java/com/github/invictum/reportportal/StepProcessorsHolderProvider.java index 3e0ea9f..7e1f932 100644 --- a/src/main/java/com/github/invictum/reportportal/StepProcessorsHolderProvider.java +++ b/src/main/java/com/github/invictum/reportportal/StepProcessorsHolderProvider.java @@ -2,11 +2,11 @@ import com.google.inject.Provider; -public class StepProcessorsHolderProvider implements Provider { +public class StepProcessorsHolderProvider implements Provider { @Override - public StepProcessorsHolder get() { - StepProcessorsHolder holder = new StepProcessorsHolder(); + public StepDataExtractorsHolder get() { + StepDataExtractorsHolder holder = new StepDataExtractorsHolder(); holder.register(ReportIntegrationConfig.get().profile().processors()); return holder; } diff --git a/src/main/java/com/github/invictum/reportportal/StepsSetProfile.java b/src/main/java/com/github/invictum/reportportal/StepsSetProfile.java index 5785fd0..671e919 100644 --- a/src/main/java/com/github/invictum/reportportal/StepsSetProfile.java +++ b/src/main/java/com/github/invictum/reportportal/StepsSetProfile.java @@ -1,10 +1,10 @@ package com.github.invictum.reportportal; -import com.github.invictum.reportportal.processor.*; +import com.github.invictum.reportportal.extractor.*; /** * Describes @{@link StepDataExtractor} sets as a unions. - * It is possible to specify CUSTOM profile and register to it any @{@link StepDataExtractor}. Order of processor is matters. + * It is possible to specify CUSTOM profile and register to it any @{@link StepDataExtractor}. Order of extractor is matters. */ public enum StepsSetProfile { diff --git a/src/main/java/com/github/invictum/reportportal/processor/FinishStep.java b/src/main/java/com/github/invictum/reportportal/extractor/FinishStep.java similarity index 93% rename from src/main/java/com/github/invictum/reportportal/processor/FinishStep.java rename to src/main/java/com/github/invictum/reportportal/extractor/FinishStep.java index 382db12..e44a22d 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/FinishStep.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/FinishStep.java @@ -1,4 +1,4 @@ -package com.github.invictum.reportportal.processor; +package com.github.invictum.reportportal.extractor; import com.github.invictum.reportportal.EnhancedMessage; import com.github.invictum.reportportal.Utils; diff --git a/src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java b/src/main/java/com/github/invictum/reportportal/extractor/HtmlSources.java similarity index 97% rename from src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java rename to src/main/java/com/github/invictum/reportportal/extractor/HtmlSources.java index ce96b04..79722bd 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/HtmlSources.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/HtmlSources.java @@ -1,4 +1,4 @@ -package com.github.invictum.reportportal.processor; +package com.github.invictum.reportportal.extractor; import com.github.invictum.reportportal.EnhancedMessage; import com.github.invictum.reportportal.Utils; diff --git a/src/main/java/com/github/invictum/reportportal/processor/SeleniumLogs.java b/src/main/java/com/github/invictum/reportportal/extractor/SeleniumLogs.java similarity index 96% rename from src/main/java/com/github/invictum/reportportal/processor/SeleniumLogs.java rename to src/main/java/com/github/invictum/reportportal/extractor/SeleniumLogs.java index c9c62d6..969479a 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/SeleniumLogs.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/SeleniumLogs.java @@ -1,4 +1,4 @@ -package com.github.invictum.reportportal.processor; +package com.github.invictum.reportportal.extractor; import com.github.invictum.reportportal.*; import com.github.invictum.reportportal.injector.IntegrationInjector; diff --git a/src/main/java/com/github/invictum/reportportal/processor/StartStep.java b/src/main/java/com/github/invictum/reportportal/extractor/StartStep.java similarity index 93% rename from src/main/java/com/github/invictum/reportportal/processor/StartStep.java rename to src/main/java/com/github/invictum/reportportal/extractor/StartStep.java index 1c65b2c..480d631 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/StartStep.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/StartStep.java @@ -1,4 +1,4 @@ -package com.github.invictum.reportportal.processor; +package com.github.invictum.reportportal.extractor; import com.github.invictum.reportportal.EnhancedMessage; import com.github.invictum.reportportal.Utils; diff --git a/src/main/java/com/github/invictum/reportportal/processor/StepDataExtractor.java b/src/main/java/com/github/invictum/reportportal/extractor/StepDataExtractor.java similarity index 92% rename from src/main/java/com/github/invictum/reportportal/processor/StepDataExtractor.java rename to src/main/java/com/github/invictum/reportportal/extractor/StepDataExtractor.java index 37c4c0b..e41d356 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/StepDataExtractor.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/StepDataExtractor.java @@ -1,4 +1,4 @@ -package com.github.invictum.reportportal.processor; +package com.github.invictum.reportportal.extractor; import com.github.invictum.reportportal.EnhancedMessage; import net.thucydides.core.model.TestStep; diff --git a/src/main/java/com/github/invictum/reportportal/processor/StepError.java b/src/main/java/com/github/invictum/reportportal/extractor/StepError.java similarity index 96% rename from src/main/java/com/github/invictum/reportportal/processor/StepError.java rename to src/main/java/com/github/invictum/reportportal/extractor/StepError.java index 5e567f2..57d4de9 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/StepError.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/StepError.java @@ -1,4 +1,4 @@ -package com.github.invictum.reportportal.processor; +package com.github.invictum.reportportal.extractor; import com.github.invictum.reportportal.EnhancedMessage; import com.github.invictum.reportportal.Utils; diff --git a/src/main/java/com/github/invictum/reportportal/processor/StepScreenshots.java b/src/main/java/com/github/invictum/reportportal/extractor/StepScreenshots.java similarity index 97% rename from src/main/java/com/github/invictum/reportportal/processor/StepScreenshots.java rename to src/main/java/com/github/invictum/reportportal/extractor/StepScreenshots.java index 6dde6e1..76cf86d 100644 --- a/src/main/java/com/github/invictum/reportportal/processor/StepScreenshots.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/StepScreenshots.java @@ -1,4 +1,4 @@ -package com.github.invictum.reportportal.processor; +package com.github.invictum.reportportal.extractor; import com.github.invictum.reportportal.EnhancedMessage; import com.github.invictum.reportportal.Utils; diff --git a/src/main/java/com/github/invictum/reportportal/handler/FlatHandler.java b/src/main/java/com/github/invictum/reportportal/handler/FlatHandler.java index 637078c..22def1b 100644 --- a/src/main/java/com/github/invictum/reportportal/handler/FlatHandler.java +++ b/src/main/java/com/github/invictum/reportportal/handler/FlatHandler.java @@ -24,7 +24,7 @@ public class FlatHandler implements Handler { Launch launch; @Inject - StepProcessorsHolder holder; + StepDataExtractorsHolder holder; Maybe suiteId; Maybe testId; diff --git a/src/main/java/com/github/invictum/reportportal/injector/SerenityPortalModule.java b/src/main/java/com/github/invictum/reportportal/injector/SerenityPortalModule.java index 85383c9..d890d14 100644 --- a/src/main/java/com/github/invictum/reportportal/injector/SerenityPortalModule.java +++ b/src/main/java/com/github/invictum/reportportal/injector/SerenityPortalModule.java @@ -3,7 +3,7 @@ import com.epam.reportportal.service.Launch; import com.github.invictum.reportportal.LogStorage; import com.github.invictum.reportportal.ReportIntegrationConfig; -import com.github.invictum.reportportal.StepProcessorsHolder; +import com.github.invictum.reportportal.StepDataExtractorsHolder; import com.github.invictum.reportportal.StepProcessorsHolderProvider; import com.google.inject.AbstractModule; import com.google.inject.Scopes; @@ -12,7 +12,7 @@ public class SerenityPortalModule extends AbstractModule { protected void configure() { bind(Launch.class).toProvider(ReportLaunchProvider.class).in(Scopes.SINGLETON); - bind(StepProcessorsHolder.class).toProvider(StepProcessorsHolderProvider.class).in(Scopes.SINGLETON); + bind(StepDataExtractorsHolder.class).toProvider(StepProcessorsHolderProvider.class).in(Scopes.SINGLETON); bind(LogStorage.class).in(Scopes.SINGLETON); bind(ReportIntegrationConfig.class).in(Scopes.SINGLETON); } diff --git a/src/test/java/com/github/invictum/reportportal/StepDataExtractorHolderTest.java b/src/test/java/com/github/invictum/reportportal/StepDataExtractorHolderTest.java deleted file mode 100644 index e3918dd..0000000 --- a/src/test/java/com/github/invictum/reportportal/StepDataExtractorHolderTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.invictum.reportportal; - -import com.github.invictum.reportportal.processor.StartStep; -import net.thucydides.core.model.TestStep; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.StrictStubs.class) -public class StepDataExtractorHolderTest { - - @Mock - private StartStep processorMock; - - @Test - public void proceedTest() { - StepProcessorsHolder holder = new StepProcessorsHolder(); - holder.register(processorMock); - TestStep step = new TestStep(); - holder.proceed(step); - Mockito.verify(processorMock, Mockito.times(1)).extract(step); - } -} diff --git a/src/test/java/com/github/invictum/reportportal/StepDataExtractorsHolderTest.java b/src/test/java/com/github/invictum/reportportal/StepDataExtractorsHolderTest.java new file mode 100644 index 0000000..79d858a --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/StepDataExtractorsHolderTest.java @@ -0,0 +1,29 @@ +package com.github.invictum.reportportal; + +import com.github.invictum.reportportal.extractor.StartStep; +import net.thucydides.core.model.TestStep; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class StepDataExtractorsHolderTest { + + @Mock + private StartStep extractorMock; + + @Mock + private TestStep stepMock; + + @Test + public void proceedTest() { + StepDataExtractorsHolder holder = new StepDataExtractorsHolder(); + holder.register(extractorMock); + // Handle clone case + Mockito.when(stepMock.clone()).thenReturn(stepMock); + holder.proceed(stepMock); + Mockito.verify(extractorMock, Mockito.times(1)).extract(stepMock); + } +} diff --git a/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java b/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java index 3d741de..4e04e9b 100644 --- a/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java +++ b/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java @@ -1,6 +1,6 @@ package com.github.invictum.reportportal; -import com.github.invictum.reportportal.processor.*; +import com.github.invictum.reportportal.extractor.*; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/src/test/java/com/github/invictum/reportportal/UtilsLogLevelTest.java b/src/test/java/com/github/invictum/reportportal/UtilsLogLevelTest.java index fe2580f..f09411f 100644 --- a/src/test/java/com/github/invictum/reportportal/UtilsLogLevelTest.java +++ b/src/test/java/com/github/invictum/reportportal/UtilsLogLevelTest.java @@ -1,6 +1,5 @@ package com.github.invictum.reportportal; -import com.github.invictum.reportportal.Utils; import net.thucydides.core.model.TestResult; import org.junit.Assert; import org.junit.Test; @@ -14,7 +13,7 @@ public class UtilsLogLevelTest { public TestResult testResult; @Parameterized.Parameter(1) - public String status; + public LogLevel status; @Test public void logLevelTest() { @@ -24,14 +23,14 @@ public void logLevelTest() { @Parameterized.Parameters(name = "{index}: {0} - {1}") public static Object[][] data() { return new Object[][]{ - {TestResult.SUCCESS, "info"}, - {TestResult.ERROR, "error"}, - {TestResult.FAILURE, "error"}, - {TestResult.PENDING, "debug"}, - {TestResult.SKIPPED, "debug"}, - {TestResult.IGNORED, "debug"}, - {TestResult.COMPROMISED, "warn"}, - {TestResult.UNDEFINED, "fatal"} + {TestResult.SUCCESS, LogLevel.INFO}, + {TestResult.ERROR, LogLevel.ERROR}, + {TestResult.FAILURE, LogLevel.ERROR}, + {TestResult.PENDING, LogLevel.DEBUG}, + {TestResult.SKIPPED, LogLevel.DEBUG}, + {TestResult.IGNORED, LogLevel.DEBUG}, + {TestResult.COMPROMISED, LogLevel.WARN}, + {TestResult.UNDEFINED, LogLevel.FATAL} }; } } diff --git a/src/test/java/com/github/invictum/reportportal/extractor/FinishStepTest.java b/src/test/java/com/github/invictum/reportportal/extractor/FinishStepTest.java new file mode 100644 index 0000000..f04a1ef --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/extractor/FinishStepTest.java @@ -0,0 +1,54 @@ +package com.github.invictum.reportportal.extractor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.LogLevel; +import net.thucydides.core.model.TestResult; +import net.thucydides.core.model.TestStep; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.time.ZonedDateTime; +import java.util.Collection; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class FinishStepTest { + + @Mock + private TestStep stepMock; + + @Test + public void successTest() { + FinishStep finishStep = new FinishStep(); + /* Setup mock */ + Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); + Mockito.when(stepMock.getDuration()).thenReturn(1000L); + Mockito.when(stepMock.getResult()).thenReturn(TestResult.SUCCESS); + Mockito.when(stepMock.getDescription()).thenReturn("Description"); + Collection logs = finishStep.extract(stepMock); + /* Verification */ + Assert.assertEquals(1, logs.size()); + EnhancedMessage actual = logs.iterator().next(); + Assert.assertEquals(LogLevel.INFO, actual.getLevel()); + Assert.assertEquals("[SUCCESS] Description", actual.getMessage()); + } + + @Test + public void errorTest() { + FinishStep finishStep = new FinishStep(); + /* Setup mock */ + Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); + Mockito.when(stepMock.getDuration()).thenReturn(1000L); + Mockito.when(stepMock.getResult()).thenReturn(TestResult.ERROR); + Mockito.when(stepMock.getDescription()).thenReturn("Error"); + Collection logs = finishStep.extract(stepMock); + /* Verification */ + Assert.assertEquals(1, logs.size()); + EnhancedMessage actual = logs.iterator().next(); + Assert.assertEquals(LogLevel.ERROR, actual.getLevel()); + Assert.assertEquals("[ERROR] Error", actual.getMessage()); + } +} diff --git a/src/test/java/com/github/invictum/reportportal/extractor/HtmlSourcesTest.java b/src/test/java/com/github/invictum/reportportal/extractor/HtmlSourcesTest.java new file mode 100644 index 0000000..3769dcd --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/extractor/HtmlSourcesTest.java @@ -0,0 +1,53 @@ +package com.github.invictum.reportportal.extractor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.LogLevel; +import net.thucydides.core.model.TestStep; +import net.thucydides.core.screenshots.ScreenshotAndHtmlSource; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.File; +import java.io.IOException; +import java.time.ZonedDateTime; +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class HtmlSourcesTest { + + @Mock + private TestStep stepMock; + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void noSources() { + HtmlSources htmlSources = new HtmlSources(); + Collection logs = htmlSources.extract(stepMock); + Assert.assertTrue(logs.isEmpty()); + } + + @Test + public void sourcesPresent() throws IOException { + HtmlSources htmlSources = new HtmlSources(); + ScreenshotAndHtmlSource screenshotMock = Mockito.mock(ScreenshotAndHtmlSource.class); + Mockito.when(stepMock.getScreenshots()).thenReturn(Collections.singletonList(screenshotMock)); + Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); + Optional source = Optional.of(folder.newFile("source.txt")); + Mockito.when(screenshotMock.getHtmlSource()).thenReturn(source); + Collection logs = htmlSources.extract(stepMock); + Assert.assertEquals(1, logs.size()); + EnhancedMessage actual = logs.iterator().next(); + Assert.assertEquals("HTML Source", actual.getMessage()); + Assert.assertEquals(LogLevel.WARN, actual.getLevel()); + } +} diff --git a/src/test/java/com/github/invictum/reportportal/extractor/StartStepTest.java b/src/test/java/com/github/invictum/reportportal/extractor/StartStepTest.java new file mode 100644 index 0000000..cf151f0 --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/extractor/StartStepTest.java @@ -0,0 +1,37 @@ +package com.github.invictum.reportportal.extractor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.LogLevel; +import net.thucydides.core.model.TestResult; +import net.thucydides.core.model.TestStep; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.time.ZonedDateTime; +import java.util.Collection; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class StartStepTest { + + @Mock + private TestStep stepMock; + + @Test + public void startStep() { + StartStep startStep = new StartStep(); + // Setup mock + Mockito.when(stepMock.getResult()).thenReturn(TestResult.SUCCESS); + Mockito.when(stepMock.getDescription()).thenReturn("Step"); + Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); + Collection logs = startStep.extract(stepMock); + // Verify + Assert.assertEquals(1, logs.size()); + EnhancedMessage actual = logs.iterator().next(); + Assert.assertEquals("[STARTED] Step", actual.getMessage()); + Assert.assertEquals(LogLevel.INFO, actual.getLevel()); + } +} diff --git a/src/test/java/com/github/invictum/reportportal/extractor/StepErrorTest.java b/src/test/java/com/github/invictum/reportportal/extractor/StepErrorTest.java new file mode 100644 index 0000000..92d9584 --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/extractor/StepErrorTest.java @@ -0,0 +1,61 @@ +package com.github.invictum.reportportal.extractor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.LogLevel; +import net.thucydides.core.model.TestResult; +import net.thucydides.core.model.TestStep; +import net.thucydides.core.model.stacktrace.FailureCause; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.time.ZonedDateTime; +import java.util.Collection; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class StepErrorTest { + + @Mock + private TestStep stepMock; + + @Mock + private FailureCause failureCauseMock; + + @Test + public void noException() { + StepError stepError = new StepError(); + Assert.assertTrue(stepError.extract(stepMock).isEmpty()); + } + + @Test + public void customErrorProcessing() { + StepError stepError = new StepError(TestStep::getConciseErrorMessage); + // Setup mock + Mockito.when(stepMock.getResult()).thenReturn(TestResult.ERROR); + Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); + Mockito.when(stepMock.getException()).thenReturn(failureCauseMock); + Mockito.when(stepMock.getConciseErrorMessage()).thenReturn("Custom error"); + EnhancedMessage actual = stepError.extract(stepMock).iterator().next(); + // Verification + Assert.assertEquals("Custom error", actual.getMessage()); + Assert.assertEquals(LogLevel.ERROR, actual.getLevel()); + } + + @Test + public void defaultError() { + StepError stepError = new StepError(); + // Setup mock + Mockito.when(stepMock.getResult()).thenReturn(TestResult.FAILURE); + Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); + Mockito.when(stepMock.getException()).thenReturn(failureCauseMock); + Mockito.when(failureCauseMock.getOriginalCause()).thenReturn(new IllegalStateException("Details")); + Collection logs = stepError.extract(stepMock); + // Verification + Assert.assertEquals(1, logs.size()); + EnhancedMessage actual = logs.iterator().next(); + Assert.assertEquals(LogLevel.ERROR, actual.getLevel()); + } +} diff --git a/src/test/java/com/github/invictum/reportportal/extractor/StepScreenshotsTest.java b/src/test/java/com/github/invictum/reportportal/extractor/StepScreenshotsTest.java new file mode 100644 index 0000000..dded75d --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/extractor/StepScreenshotsTest.java @@ -0,0 +1,52 @@ +package com.github.invictum.reportportal.extractor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.LogLevel; +import net.thucydides.core.model.TestResult; +import net.thucydides.core.model.TestStep; +import net.thucydides.core.screenshots.ScreenshotAndHtmlSource; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.IOException; +import java.time.ZonedDateTime; +import java.util.Collection; +import java.util.Collections; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class StepScreenshotsTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Mock + private TestStep stepMock; + + @Test + public void noScreenshots() { + StepScreenshots stepScreenshots = new StepScreenshots(); + Collection logs = stepScreenshots.extract(stepMock); + Assert.assertTrue(logs.isEmpty()); + } + + @Test + public void screenshotPresent() throws IOException { + StepScreenshots stepsScreenshots = new StepScreenshots(); + ScreenshotAndHtmlSource screenshotMock = Mockito.mock(ScreenshotAndHtmlSource.class); + Mockito.when(stepMock.getResult()).thenReturn(TestResult.SUCCESS); + Mockito.when(stepMock.getScreenshots()).thenReturn(Collections.singletonList(screenshotMock)); + Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); + Mockito.when(screenshotMock.getScreenshot()).thenReturn(folder.newFile("image.png")); + Collection logs = stepsScreenshots.extract(stepMock); + Assert.assertEquals(1, logs.size()); + EnhancedMessage actual = logs.iterator().next(); + Assert.assertEquals("Screenshot", actual.getMessage()); + Assert.assertEquals(LogLevel.INFO, actual.getLevel()); + } +} diff --git a/src/test/java/com/github/invictum/reportportal/processor/FinishStepTest.java b/src/test/java/com/github/invictum/reportportal/processor/FinishStepTest.java deleted file mode 100644 index 5fc2238..0000000 --- a/src/test/java/com/github/invictum/reportportal/processor/FinishStepTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import net.thucydides.core.model.TestResult; -import net.thucydides.core.model.TestStep; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; - -import java.time.ZonedDateTime; - -@RunWith(MockitoJUnitRunner.StrictStubs.class) -public class FinishStepTest { - - @Mock - private TestStep stepMock; - - @Test - public void finishStepLoggerTest() { - FinishStep finishStep = new FinishStep(); - /* Setup mock */ - Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); - Mockito.when(stepMock.getResult()).thenReturn(TestResult.SUCCESS); - Mockito.when(stepMock.getDuration()).thenReturn(1000L); - finishStep.extract(stepMock); - /* Verification */ - Mockito.verify(stepMock, Mockito.times(1)).getStartTime(); - Mockito.verify(stepMock, Mockito.times(1)).getDescription(); - Mockito.verify(stepMock, Mockito.times(1)).getDuration(); - Mockito.verify(stepMock, Mockito.times(2)).getResult(); - } -} diff --git a/src/test/java/com/github/invictum/reportportal/processor/HtmlSourcesTest.java b/src/test/java/com/github/invictum/reportportal/processor/HtmlSourcesTest.java deleted file mode 100644 index bb66f31..0000000 --- a/src/test/java/com/github/invictum/reportportal/processor/HtmlSourcesTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import net.thucydides.core.model.TestStep; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.StrictStubs.class) -public class HtmlSourcesTest { - - @Mock - private TestStep stepMock; - - @Test - public void noScreenshotsTest() { - HtmlSources htmlSources = new HtmlSources(); - htmlSources.extract(stepMock); - Mockito.verify(stepMock, Mockito.never()).getResult(); - } -} diff --git a/src/test/java/com/github/invictum/reportportal/processor/StartStepTest.java b/src/test/java/com/github/invictum/reportportal/processor/StartStepTest.java deleted file mode 100644 index 6c163af..0000000 --- a/src/test/java/com/github/invictum/reportportal/processor/StartStepTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import net.thucydides.core.model.TestStep; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; - -import java.time.ZonedDateTime; - -@RunWith(MockitoJUnitRunner.StrictStubs.class) -public class StartStepTest { - - @Mock - private TestStep stepMock; - - @Test - public void startStepLoggerTest() { - StartStep startStep = new StartStep(); - /* Setup mock */ - Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); - startStep.extract(stepMock); - Mockito.verify(stepMock, Mockito.times(1)).getStartTime(); - Mockito.verify(stepMock, Mockito.times(1)).getDescription(); - Mockito.verify(stepMock, Mockito.times(1)).getResult(); - } -} diff --git a/src/test/java/com/github/invictum/reportportal/processor/StepErrorTest.java b/src/test/java/com/github/invictum/reportportal/processor/StepErrorTest.java deleted file mode 100644 index 3331008..0000000 --- a/src/test/java/com/github/invictum/reportportal/processor/StepErrorTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import net.thucydides.core.model.TestStep; -import net.thucydides.core.model.stacktrace.FailureCause; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; - -import java.time.ZonedDateTime; - -@RunWith(MockitoJUnitRunner.StrictStubs.class) -public class StepErrorTest { - - @Mock - private TestStep stepMock; - - @Mock - private FailureCause failureCauseMock; - - @Test - public void noExceptionTest() { - StepError stepError = new StepError(); - stepError.extract(stepMock); - Mockito.verify(stepMock, Mockito.times(1)).getException(); - Mockito.verify(stepMock, Mockito.never()).getConciseErrorMessage(); - } - - @Test - public void customFormatExceptionLogTest() { - StepError stepError = new StepError(TestStep::getConciseErrorMessage); - /* Setup mock */ - Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); - Mockito.when(stepMock.getException()).thenReturn(failureCauseMock); - stepError.extract(stepMock); - /* Verification */ - Mockito.verify(stepMock, Mockito.times(1)).getException(); - Mockito.verify(stepMock, Mockito.times(1)).getConciseErrorMessage(); - Mockito.verify(stepMock, Mockito.times(1)).getResult(); - } - - @Test - public void fullExceptionLogTest() { - StepError stepError = new StepError(); - /* Setup mock */ - Mockito.when(stepMock.getStartTime()).thenReturn(ZonedDateTime.now()); - Mockito.when(stepMock.getException()).thenReturn(failureCauseMock); - Mockito.when(failureCauseMock.getOriginalCause()).thenReturn(new IllegalStateException("Details")); - stepError.extract(stepMock); - /* Verification */ - Mockito.verify(stepMock, Mockito.times(2)).getException(); - Mockito.verify(stepMock, Mockito.times(1)).getResult(); - } -} diff --git a/src/test/java/com/github/invictum/reportportal/processor/StepScreenshotsTest.java b/src/test/java/com/github/invictum/reportportal/processor/StepScreenshotsTest.java deleted file mode 100644 index 77e47d5..0000000 --- a/src/test/java/com/github/invictum/reportportal/processor/StepScreenshotsTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.github.invictum.reportportal.processor; - -import net.thucydides.core.model.TestStep; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.StrictStubs.class) -public class StepScreenshotsTest { - - @Mock - private TestStep stepMock; - - @Test - public void noScreenshotsTest() { - StepScreenshots stepScreenshots = new StepScreenshots(); - stepScreenshots.extract(stepMock); - Mockito.verify(stepMock, Mockito.never()).getResult(); - } -} From 53a8004e976fb7dcd6593f8ec9f1d300587cd386 Mon Sep 17 00:00:00 2001 From: Iaroslav Iershov Date: Mon, 16 Jul 2018 14:57:49 +0300 Subject: [PATCH 4/5] #34: Updated implementation: - removed equals method for Extractors - added unit tests --- .../reportportal/EnhancedMessage.java | 5 +- .../StepProcessorsHolderProvider.java | 2 +- .../reportportal/StepsSetProfile.java | 38 +++++++------- .../reportportal/extractor/FinishStep.java | 5 -- .../reportportal/extractor/HtmlSources.java | 7 +-- .../reportportal/extractor/SeleniumLogs.java | 9 +--- .../reportportal/extractor/StartStep.java | 5 -- .../reportportal/extractor/StepError.java | 5 -- .../extractor/StepScreenshots.java | 5 -- .../reportportal/handler/TreeHandler.java | 2 +- .../reportportal/EnhancedMessageTest.java | 19 +++++++ .../invictum/reportportal/ItemTypeTest.java | 20 ++++++++ .../reportportal/StepsSetProfileTest.java | 44 ++++++----------- .../extractor/SeleniumLogsTest.java | 49 +++++++++++++++++++ 14 files changed, 129 insertions(+), 86 deletions(-) create mode 100644 src/test/java/com/github/invictum/reportportal/EnhancedMessageTest.java create mode 100644 src/test/java/com/github/invictum/reportportal/ItemTypeTest.java create mode 100644 src/test/java/com/github/invictum/reportportal/extractor/SeleniumLogsTest.java diff --git a/src/main/java/com/github/invictum/reportportal/EnhancedMessage.java b/src/main/java/com/github/invictum/reportportal/EnhancedMessage.java index 088c8ec..91d0f49 100644 --- a/src/main/java/com/github/invictum/reportportal/EnhancedMessage.java +++ b/src/main/java/com/github/invictum/reportportal/EnhancedMessage.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.util.Calendar; import java.util.Date; +import java.util.Objects; /** * Improved version of {@link ReportPortalMessage} that extended with details related to log level and date. @@ -35,12 +36,12 @@ public EnhancedMessage(File file, String message) throws IOException { } public EnhancedMessage withLevel(LogLevel level) { - this.level = level; + this.level = Objects.requireNonNull(level, "Log level must not be null"); return this; } public EnhancedMessage withDate(Date date) { - this.date = date; + this.date = Objects.requireNonNull(date, "Message date must not be null"); return this; } diff --git a/src/main/java/com/github/invictum/reportportal/StepProcessorsHolderProvider.java b/src/main/java/com/github/invictum/reportportal/StepProcessorsHolderProvider.java index 7e1f932..d98110c 100644 --- a/src/main/java/com/github/invictum/reportportal/StepProcessorsHolderProvider.java +++ b/src/main/java/com/github/invictum/reportportal/StepProcessorsHolderProvider.java @@ -7,7 +7,7 @@ public class StepProcessorsHolderProvider implements Provider extract(final TestStep step) { message.withDate(Utils.stepEndDate(step)).withLevel(Utils.logLevel(step.getResult())); return Collections.singleton(message); } - - @Override - public boolean equals(Object obj) { - return obj instanceof FinishStep; - } } diff --git a/src/main/java/com/github/invictum/reportportal/extractor/HtmlSources.java b/src/main/java/com/github/invictum/reportportal/extractor/HtmlSources.java index 79722bd..2328d1b 100644 --- a/src/main/java/com/github/invictum/reportportal/extractor/HtmlSources.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/HtmlSources.java @@ -14,7 +14,7 @@ import java.util.*; /** - * Attaches HTML sources to Report Portal log if present + * Extracts details about HTML sources from {@link TestStep} if present */ public class HtmlSources implements StepDataExtractor { @@ -44,9 +44,4 @@ public Collection extract(final TestStep step) { } return sources; } - - @Override - public boolean equals(Object obj) { - return obj instanceof HtmlSources; - } } diff --git a/src/main/java/com/github/invictum/reportportal/extractor/SeleniumLogs.java b/src/main/java/com/github/invictum/reportportal/extractor/SeleniumLogs.java index 969479a..db46230 100644 --- a/src/main/java/com/github/invictum/reportportal/extractor/SeleniumLogs.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/SeleniumLogs.java @@ -33,11 +33,11 @@ public SeleniumLogs() { @Override public Collection extract(final TestStep step) { - long start = Utils.stepEndDate(step).getTime(); + long start = Utils.stepStartDate(step).getTime(); long end = Utils.stepEndDate(step).getTime(); LogStorage storage = IntegrationInjector.getInjector().getInstance(LogStorage.class); Set logs = new HashSet<>(); - storage.query(filter.and(entry -> start <= entry.getTimestamp() && entry.getTimestamp() >= end)) + storage.query(filter.and(entry -> start >= entry.getTimestamp() && entry.getTimestamp() <= end)) .forEach(log -> { String message = String.format("[Selenium-%s] [%s] %s", log.getType(), log.getLevel(), log.getMessage()); EnhancedMessage entry = new EnhancedMessage(message).withLevel(LogLevel.DEBUG).withDate(new Date(log.getTimestamp())); @@ -45,9 +45,4 @@ public Collection extract(final TestStep step) { }); return logs; } - - @Override - public boolean equals(Object obj) { - return obj instanceof SeleniumLogs; - } } diff --git a/src/main/java/com/github/invictum/reportportal/extractor/StartStep.java b/src/main/java/com/github/invictum/reportportal/extractor/StartStep.java index 480d631..68720ee 100644 --- a/src/main/java/com/github/invictum/reportportal/extractor/StartStep.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/StartStep.java @@ -19,9 +19,4 @@ public Collection extract(final TestStep step) { EnhancedMessage message = new EnhancedMessage("[STARTED] " + step.getDescription()); return Collections.singleton(message.withDate(startDate).withLevel(Utils.logLevel(step.getResult()))); } - - @Override - public boolean equals(Object obj) { - return obj instanceof StartStep; - } } diff --git a/src/main/java/com/github/invictum/reportportal/extractor/StepError.java b/src/main/java/com/github/invictum/reportportal/extractor/StepError.java index 57d4de9..617b10f 100644 --- a/src/main/java/com/github/invictum/reportportal/extractor/StepError.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/StepError.java @@ -47,9 +47,4 @@ public Collection extract(final TestStep step) { } return Collections.emptySet(); } - - @Override - public boolean equals(Object obj) { - return obj instanceof StepError; - } } diff --git a/src/main/java/com/github/invictum/reportportal/extractor/StepScreenshots.java b/src/main/java/com/github/invictum/reportportal/extractor/StepScreenshots.java index 76cf86d..507ae91 100644 --- a/src/main/java/com/github/invictum/reportportal/extractor/StepScreenshots.java +++ b/src/main/java/com/github/invictum/reportportal/extractor/StepScreenshots.java @@ -41,9 +41,4 @@ public Collection extract(final TestStep step) { } return messages; } - - @Override - public boolean equals(Object obj) { - return obj instanceof StepScreenshots; - } } diff --git a/src/main/java/com/github/invictum/reportportal/handler/TreeHandler.java b/src/main/java/com/github/invictum/reportportal/handler/TreeHandler.java index c5f6ab8..147f0a5 100644 --- a/src/main/java/com/github/invictum/reportportal/handler/TreeHandler.java +++ b/src/main/java/com/github/invictum/reportportal/handler/TreeHandler.java @@ -43,7 +43,7 @@ private void push(Maybe parent, List steps) { startTest.setType(ItemType.TEST.key()); startTest.setStartTime(Utils.stepStartDate(testStep)); Maybe current = launch.startTestItem(parent, startTest); - /* Proceed current step through processors */ + /* Proceed current step through extractors */ holder.proceed(testStep); /* Proceed children if present */ if (testStep.hasChildren()) { diff --git a/src/test/java/com/github/invictum/reportportal/EnhancedMessageTest.java b/src/test/java/com/github/invictum/reportportal/EnhancedMessageTest.java new file mode 100644 index 0000000..7570f28 --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/EnhancedMessageTest.java @@ -0,0 +1,19 @@ +package com.github.invictum.reportportal; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class EnhancedMessageTest { + + @Test(expected = NullPointerException.class) + public void setDateWithNull() { + new EnhancedMessage("Text").withDate(null); + } + + @Test(expected = NullPointerException.class) + public void setLevelWithNull() { + new EnhancedMessage("Text").withLevel(null); + } +} diff --git a/src/test/java/com/github/invictum/reportportal/ItemTypeTest.java b/src/test/java/com/github/invictum/reportportal/ItemTypeTest.java new file mode 100644 index 0000000..c0ab44b --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/ItemTypeTest.java @@ -0,0 +1,20 @@ +package com.github.invictum.reportportal; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class ItemTypeTest { + + @Test + public void suiteKey() { + Assert.assertEquals("TEST", ItemType.SUITE.key()); + } + + @Test + public void testKey() { + Assert.assertEquals("STEP", ItemType.TEST.key()); + } +} diff --git a/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java b/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java index 4e04e9b..b7d50bc 100644 --- a/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java +++ b/src/test/java/com/github/invictum/reportportal/StepsSetProfileTest.java @@ -1,6 +1,8 @@ package com.github.invictum.reportportal; -import com.github.invictum.reportportal.extractor.*; +import com.github.invictum.reportportal.extractor.HtmlSources; +import com.github.invictum.reportportal.extractor.StepDataExtractor; +import com.github.invictum.reportportal.extractor.StepScreenshots; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -11,58 +13,40 @@ public class StepsSetProfileTest { @Test public void fullProfile() { - StepDataExtractor[] actual = StepsSetProfile.FULL.processors(); - StepDataExtractor[] expected = new StepDataExtractor[]{ - new StartStep(), - new StepScreenshots(), - new FinishStep(), - new StepError(), - new HtmlSources(), - new SeleniumLogs() - }; - Assert.assertArrayEquals(actual, expected); + StepDataExtractor[] actual = StepsSetProfile.FULL.extractors(); + Assert.assertEquals(6, actual.length); } @Test(expected = UnsupportedOperationException.class) public void fullProfileCustomization() { - StepsSetProfile.FULL.registerProcessors(new StepScreenshots()); + StepsSetProfile.FULL.registerExtractors(new StepScreenshots()); } @Test public void defaultProfile() { - StepDataExtractor[] actual = StepsSetProfile.DEFAULT.processors(); - StepDataExtractor[] expected = new StepDataExtractor[]{ - new FinishStep(), - new StepScreenshots(), - new StepError() - }; - Assert.assertArrayEquals(actual, expected); + StepDataExtractor[] actual = StepsSetProfile.DEFAULT.extractors(); + Assert.assertEquals(3, actual.length); } @Test(expected = UnsupportedOperationException.class) public void defaultProfileCustomization() { - StepsSetProfile.DEFAULT.registerProcessors(new StepScreenshots()); + StepsSetProfile.DEFAULT.registerExtractors(new StepScreenshots()); } @Test public void customProfileCustomization() { - StepsSetProfile profile = StepsSetProfile.CUSTOM.registerProcessors(new StepScreenshots()); - StepDataExtractor[] expected = new StepDataExtractor[]{new StepScreenshots()}; - Assert.assertArrayEquals(profile.processors(), expected); + StepsSetProfile profile = StepsSetProfile.CUSTOM.registerExtractors(new StepScreenshots()); + Assert.assertEquals(profile.extractors().length, 1); } @Test public void treeOptimizedProfile() { - StepDataExtractor[] actual = StepsSetProfile.TREE_OPTIMIZED.processors(); - StepDataExtractor[] expected = new StepDataExtractor[]{ - new StepScreenshots(), - new StepError() - }; - Assert.assertArrayEquals(actual, expected); + StepDataExtractor[] actual = StepsSetProfile.TREE_OPTIMIZED.extractors(); + Assert.assertEquals(2, actual.length); } @Test(expected = UnsupportedOperationException.class) public void treeOptimizedProfileCustomization() { - StepsSetProfile.TREE_OPTIMIZED.registerProcessors(new HtmlSources()); + StepsSetProfile.TREE_OPTIMIZED.registerExtractors(new HtmlSources()); } } diff --git a/src/test/java/com/github/invictum/reportportal/extractor/SeleniumLogsTest.java b/src/test/java/com/github/invictum/reportportal/extractor/SeleniumLogsTest.java new file mode 100644 index 0000000..f4a2d17 --- /dev/null +++ b/src/test/java/com/github/invictum/reportportal/extractor/SeleniumLogsTest.java @@ -0,0 +1,49 @@ +package com.github.invictum.reportportal.extractor; + +import com.github.invictum.reportportal.EnhancedMessage; +import com.github.invictum.reportportal.LogLevel; +import com.github.invictum.reportportal.LogStorage; +import com.github.invictum.reportportal.injector.IntegrationInjector; +import net.thucydides.core.model.TestStep; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.openqa.selenium.logging.LogEntries; +import org.openqa.selenium.logging.LogEntry; +import org.openqa.selenium.logging.Logs; + +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.logging.Level; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class SeleniumLogsTest { + + @Mock + private TestStep stepMock; + + private LogStorage storage = IntegrationInjector.getInjector().getInstance(LogStorage.class); + + @Test + public void seleniumLog() { + // Setup mock + Logs logsMock = Mockito.mock(Logs.class); + Mockito.when(logsMock.getAvailableLogTypes()).thenReturn(Collections.singleton("browser")); + ZonedDateTime start = ZonedDateTime.now(); + LogEntry entry = new LogEntry(Level.INFO, start.toEpochSecond() * 1000, "Message"); + LogEntries entries = new LogEntries(Collections.singleton(entry)); + Mockito.when(logsMock.get("browser")).thenReturn(entries); + storage.clean(); + storage.collect(logsMock); + Mockito.when(stepMock.getStartTime()).thenReturn(start); + Mockito.when(stepMock.getDuration()).thenReturn(1000L); + // Verify + SeleniumLogs seleniumLogs = new SeleniumLogs(); + EnhancedMessage actual = seleniumLogs.extract(stepMock).iterator().next(); + Assert.assertEquals("[Selenium-browser] [INFO] Message", actual.getMessage()); + Assert.assertEquals(LogLevel.DEBUG, actual.getLevel()); + } +} From 1d1b9e646d7b4fe0c2b08c72cf6eb855f7f8d234 Mon Sep 17 00:00:00 2001 From: Iaroslav Iershov Date: Mon, 16 Jul 2018 16:24:40 +0300 Subject: [PATCH 5/5] #34: Updated documentation in accordance to changes --- README.md | 79 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index eeaa8f1..e46b344 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Setup To add support of integration between Serenity and Report Portal simply add dependencies to your project based on used build tool. > **Warning** -> Don't add any extra Report Portal listeners or agents. Integration is provided by single module for all availavle Serenity approaches +> Don't add any extra Report Portal listeners or agents. Integration is provided by single module for all available Serenity approaches **Maven** @@ -42,9 +42,9 @@ Report Portal core libraries are used, but they placed in a separate repository, Edit `build.gradle` file in the project root ``` -compile group: 'com.github.invictum', name: 'serenity-reportportal-integration', version: '1.2.0' +compile: 'com.github.invictum:serenity-reportportal-integration:1.2.0' ``` -External Report Portal repository should be defined the same as for Maven +External Report Portal repository should be defined as the same as for Maven ``` repositories { maven { @@ -74,12 +74,12 @@ It is also possible to use Report portal integration with log frameworks in orde **Native Serenity reporting** -Serenity TAF provides its own reporting facility, but `serenity-reportportal-integration` may be used in parralel with it or independently. Both reporting mechanisms should be configured accordingly and do not depends on each other. +Serenity TAF may produce its own reporting facility via separate plugins. But `serenity-reportportal-integration` may be used in parallel with it or independently. Both reporting mechanisms should be configured accordingly and do not depends on each other. Integration configuration ------------- -All available configurations are provided via `ReportIntegrationConfig` object. Each set method returns object itself, so chain of configuration is posssible: +All available configurations are provided via `ReportIntegrationConfig` object. Each set method returns object itself, so chain of configuration is possible: ``` ReportIntegrationConfig configuration = ReportIntegrationConfig.get(); configuration.useHandler(HandlerType.TREE).useProfile(StepsSetProfile.TREE_OPTIMIZED); @@ -90,7 +90,7 @@ All integration configurations should be provided before Serenity facility init **Profiles** -Each Serenity `TestStep` object is passed through chain of configured `StepProcessors`. This approach allows to flexible configure reporting behaviour on a step level. By default integration provides following configuration profiles: +Each Serenity `TestStep` object is passed through chain of configured `StepDataExtractors`. This approach allows to flexible configure reporting behaviour on a step level. By default integration provides following configuration profiles: - DEFAULT - FULL @@ -99,67 +99,74 @@ Each Serenity `TestStep` object is passed through chain of configured `StepProce `DEFAULT` profile is used by default and contains all usually required reporting details. It generates in Report Portal a nice log that does not cluttered with extra details. -`FULL` profile contains all available `StepProcessors` and generates full reporting. Sutable for demo purposes in order to choose a set of processors. +`FULL` profile contains all available `StepDataExtractors` and generates full reporting. It suitable for demo purposes in order to choose a set of processors. -`TREE_OPTIMIZED` profile is sutable to use with `TREE` handler type. Refer to Handler Type section for more details. +`TREE_OPTIMIZED` profile is suitable to use with `TREE` handler type. Refer to Handler Type section for more details. -To customize what should be logged `CUSTOM` profile should be used. In following example `CUSTOM` profile with `StartStepLogger` and `FinishStepLogger` processors is configured. +To configure what should be logged manually `CUSTOM` profile should be used. In following example `CUSTOM` profile with `StartStep` and `FinishStep` executors is configured. ``` StepsSetProfile profile = StepsSetProfile.CUSTOM; -profile.registerProcessors(new StartStepLogger(), new FinishStepLogger()); +profile.registerProcessors(new StartStep(), new FinishStep()); ReportIntegrationConfig.get().useProfile(profile); ``` -**Processors** +**Executors** -All step processors available out of the box may be observed in `com.github.invictum.reportportal.extractor` package. +All step executors are available out of the box may be observed in `com.github.invictum.reportportal.extractor` package. For now following processors are available: -- `StartStepLogger` logs all started steps. -- `FinishStepLogger` logs all finished steps. Log level depends on step results. -- `ErrorLogger` reports error if present. Includes regular errors as well as assertion fails. By default full stack strace will be reported. But it is possible to pass a function to the constructor in order to implement any logic for message formatting. +- `StartStep` retrieves step's data relevant to its start. +- `FinishStep` extracts step's data related to its finish. Log level depends on step result. +- `StepError` extracts step's error if present. Includes regular errors as well as assertion fails. By default full stack trace will be reported. But it is possible to pass a function to the constructor in order to implement any logic for message formatting. ``` StepsSetProfile profile = StepsSetProfile.CUSTOM; -// Report full stack stace supplied by Serenity -ErrorLogger errorLogger = new ErrorLogger(); -// Report a short error description provided by Serenity -ErrorLogger errorLogger = new ErrorLogger(TestStep::getConciseErrorMessage); -profile.registerProcessors(errorLogger); +// Extract a full stack stace supplied by Serenity +StepError error = new StepError(); +// Extract only a short error description provided by Serenity +StepError error = new StepError(TestStep::getConciseErrorMessage); +profile.registerProcessors(error); ``` -- `ScreenshotAttacher` emits screenshots to RP if present. It simply attaches all available step's screenshots, so screenshot strategy is configured on Serenity level. -- `HtmlSourceAttacher` logs page source if available. -- `SeleniumLogsAttacher` reports logs supplied by Selenium. By default emits all available logs. It is possible to pass predicate to constructor in order to push particular logs. +- `StepScreenshots` extracts screenshots if present. It simply retrieves all available step's screenshots, so screenshot strategy is configured on Serenity level. +- `StepHtmlSources` extracts page source if available. +- `SeleniumLogs` retrieves logs supplied by Selenium. By default extracts all available logs. It is possible to pass predicate to constructor in order to push particular logs. ``` StepsSetProfile profile = StepsSetProfile.CUSTOM; // Collect only browser related logs -SeleniumLogsAttacher logsAttacher = new SeleniumLogsAttacher(log -> log.getType().contentEquals("browser")); -profile.registerProcessors(errorLogger); +SeleniumLogs logs = new SeleniumLogs(log -> log.getType().contentEquals("browser")); +profile.registerProcessors(logs); ``` -It is possible to use integrated processors as well as implemented by your own. To make own extractor implement `StepProcessor` interface. In custom implementation access to Serenity's `TestStep` object is provided +It is possible to use integrated extractors as well as implemented by your own. To make own extractor implement `StepDataExtractor` interface. In custom implementation access to Serenity's `TestStep` object is provided. +For example let's implement extractor that generates a log message before each step start (yeap it is pretty useful) ``` -public class MyCustomLoggerLogger implements StepProcessor { +public class GreetingExtractor implements StepDataExtractor { @Override - public void proceed(final TestStep step) { - // You logic here to emit logs + public Collection extract(final TestStep step) { + Date startDate = Utils.stepStartDate(step); + // Create an istance of EnhancedMessage that is able to hold a log message + EnhancedMessage message = new EnhancedMessage("Hello from started step " + step.getDescription()); + // Do not forget to set propper log level and timestamp + message.withDate(startDate).withLevel(Utils.logLevel(step.getResult()); + // Extractor may produce several logs for emit, but this example supplyies only one + return Collections.singleton(message); } } ``` > **Warning** -> To emit log to Report Portal time should be specified. If log timestamp is out of range of step it won't be emitted at all. `TestStep` object contains all data to calculate start, end dates and duration +> To emit log to Report Portal date should be specified. If log timestamp is out of range of step it won't be emitted at all. `TestStep` object contains all data to calculate start, end dates and duration -The order of processors registration is matters, this order the same as order of invocation. Nevertheless, log entities pushed to Report Portal will be sorted based on timestamp. +Extracted collection of `EnhancedMessage` will be used to push logs to to Report Portal and their order will be based on timestamp. -**Handler type (expiremental feature)** +**Handler type (experimental feature)** Integration provides two strategies of storing Serenity's test data to Report Portal facility: -- *FLAT* (default behaviour) - Represents steps data as plain logs emmited to the test scope +- *FLAT* (default behaviour) - Represents steps data as plain logs emitted to the test scope - *TREE* - Reconstructs steps structure as a tree representation in RP -Report Portal has a few limitations regurding to flexible nested structures support for now. As a result test report may contain some inaccuracate data. +Report Portal has a few limitations regarding to flexible nested structures support for now. As a result test report may contain some inaccurate data. E. g. test count for launch will show total number of tests + total number of steps. -Nevertheless `TREE` configuration allows to get additional features with RP. E. g. integrated RP test analisys facility scope will be changed from test to step. +Nevertheless `TREE` configuration allows to get additional features with RP. E. g. integrated RP test analysis facility scope will be changed from test to step. Handler type may be changed with following configuration ``` @@ -168,7 +175,7 @@ ReportIntegrationConfig.get().useHandler(HandlerType.TREE); **Narrative formatter** -By default, narrative is formatted as a bullet list before storring to the test description field. It is possible to alter this logic in accordance to project needs. +By default, narrative is formatted as a bullet list before storing to the test description field. It is possible to alter this logic in accordance to project needs. To achieve it implement `NarrativeFormatter` interface and define your own implementation of formatter. For example ```