diff --git a/java.json b/java.json index c0b14892..6c6028cd 100644 --- a/java.json +++ b/java.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.0.0", + "version": "1.0.1", "description": "Java support for gauge", "install": { "windows": [], diff --git a/notice.md b/notice.md index 9df64904..3d5486d4 100644 --- a/notice.md +++ b/notice.md @@ -6,7 +6,7 @@ | reflections | Copyright (C) 2004 Sam Hocevar | Java runtime metadata analysis | https://github.com/ronmamo/reflections | wtfpl version 2 | https://code.google.com/p/reflections/source/browse/trunk/COPYING.txt | | javassist | Copyright (C) 1999-2015 Shigeru Chiba. | Java bytecode engineering toolkit | https://www.javassist.org/ | Triple License: MPL 1.1, LGPL 2.1, Apache 2.0 | https://www.apache.org/licenses/LICENSE-2.0 | | javaparser | | Java 1-21 Parser and Abstract Syntax Tree for Java with advanced analysis functionalities. | https://github.com/javaparser/javaparser | Dual License: LGPL 3.0, Apache 2.0 | https://www.apache.org/licenses/LICENSE-2.0 | -| JSON-java | | A reference implementation of a JSON package in Java. | https://github.com/stleary/JSON-java | Public Domain | https://github.com/stleary/JSON-java/blob/master/LICENSE | | guava | Copyright (C) 2012 The Guava Authors | Google Core Libraries for Java | https://github.com/google/guava | Apache 2.0 | https://www.apache.org/licenses/LICENSE-2.0 | +| gson | | A Java serialization/deserialization library to convert Java Objects into JSON and back | https://github.com/google/gson | Apache 2.0 | https://www.apache.org/licenses/LICENSE-2.0 | | protobuf-java | | Java Protocol Buffers runtime library | https://github.com/protocolbuffers/protobuf | BSD 2 clause license | https://www.opensource.org/licenses/bsd-license.php | | grpc-java | | Google Core Libraries for Java | https://github.com/grpc/grpc-java | Apache 2.0 | https://www.apache.org/licenses/LICENSE-2.0 | diff --git a/pom.xml b/pom.xml index 30f791cd..3b261b46 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ gauge-java com.thoughtworks.gauge gauge-java - 1.0.0 + 1.0.1 Java plugin for Gauge https://github.com/getgauge/gauge-java @@ -55,9 +55,15 @@ 3.27.1 - org.json - json - 20250517 + com.google.code.gson + gson + 2.13.2 + + + com.google.errorprone + error_prone_annotations + + com.google.protobuf @@ -137,6 +143,10 @@ com.google.errorprone error_prone_annotations + + org.codehaus.mojo + animal-sniffer-annotations + @@ -340,8 +350,8 @@ Gauge Team getgauge@googlegroups.com - ThoughtWorks - https://thoughtworks.com/ + Gauge Team + https://gauge.org/ diff --git a/src/main/java/com/thoughtworks/gauge/AfterClassSteps.java b/src/main/java/com/thoughtworks/gauge/AfterClassSteps.java deleted file mode 100644 index 88bf86c4..00000000 --- a/src/main/java/com/thoughtworks/gauge/AfterClassSteps.java +++ /dev/null @@ -1,40 +0,0 @@ -/*---------------------------------------------------------------- - * Copyright (c) ThoughtWorks, Inc. - * Licensed under the Apache License, Version 2.0 - * See LICENSE.txt in the project root for license information. - *----------------------------------------------------------------*/ -package com.thoughtworks.gauge; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Methods annotated with this hook, will be executed after every step in that particular class. - *

- * If there is more than one method annotated with @AfterClassSteps the order of execution is as follows: - *

    - *
  • Hooks which are not filtered by tags. - *
  • Hooks filtered by tags. - *
- * If there is more than one hook of these categories, they are executed in reverse alphabetical order based on method names. - *

- */ -@Target(ElementType.METHOD) -@Deprecated -@Retention(RetentionPolicy.RUNTIME) -public @interface AfterClassSteps { - - /** - * @return Array of tags to filter which steps the hook executes after based on the tags in the current scenario and spec. - */ - String[] tags() default {}; - - /** - * @return OR: if hook should execute for the current execution context (spec and scenario) containing any of the tags provided - * AND: if hook should execute for the current execution context (spec and scenario) containing all of the tags provided - * Default is AND - */ - Operator tagAggregation() default Operator.AND; -} diff --git a/src/main/java/com/thoughtworks/gauge/BeforeClassSteps.java b/src/main/java/com/thoughtworks/gauge/BeforeClassSteps.java deleted file mode 100644 index 5dcc7b1e..00000000 --- a/src/main/java/com/thoughtworks/gauge/BeforeClassSteps.java +++ /dev/null @@ -1,40 +0,0 @@ -/*---------------------------------------------------------------- - * Copyright (c) ThoughtWorks, Inc. - * Licensed under the Apache License, Version 2.0 - * See LICENSE.txt in the project root for license information. - *----------------------------------------------------------------*/ -package com.thoughtworks.gauge; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Methods annotated with this hook, will execute before every step in that particular class. - *

- * If there is more than one method annotated with @BeforeClassSteps the order of execution is as follows: - *

    - *
  • Hooks which are not filtered by tags. - *
  • Hooks filtered by tags. - *
- * If there is more than one hook of these categories, they are alphabetically sorted based on method names. - *

- */ -@Target(ElementType.METHOD) -@Deprecated -@Retention(RetentionPolicy.RUNTIME) -public @interface BeforeClassSteps { - - /** - * @return Array of tags to filter which steps the hook executes before based on the tags in the current scenario and spec. - */ - String[] tags() default {}; - - /** - * @return OR: if hook should execute for the current execution context (spec and scenario) containing any of the tags provided - * AND: if hook should execute for the current execution context (spec and scenario) containing all of the tags provided - * Default is AND - */ - Operator tagAggregation() default Operator.AND; -} diff --git a/src/main/java/com/thoughtworks/gauge/Logger.java b/src/main/java/com/thoughtworks/gauge/Logger.java index 27c11e32..e1bfc91d 100644 --- a/src/main/java/com/thoughtworks/gauge/Logger.java +++ b/src/main/java/com/thoughtworks/gauge/Logger.java @@ -5,8 +5,10 @@ *----------------------------------------------------------------*/ package com.thoughtworks.gauge; -import org.assertj.core.util.Throwables; -import org.json.JSONObject; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; public class Logger { public static void info(String message) { @@ -18,7 +20,7 @@ public static void error(String message) { } public static void error(String message, Throwable t) { - error(String.format("%s\n%s\n%s", message, t.getMessage(), Throwables.getStackTrace(t))); + error(String.format("%s\n%s\n%s", message, t.getMessage(), Util.stacktraceFrom(t))); } public static void warning(String message) { @@ -26,7 +28,7 @@ public static void warning(String message) { } public static void warning(String message, Throwable t) { - warning(String.format("%s\n%s\n%s", message, t.getMessage(), Throwables.getStackTrace(t))); + warning(String.format("%s\n%s\n%s", message, t.getMessage(), Util.stacktraceFrom(t))); } public static void debug(String message) { @@ -39,22 +41,27 @@ public static void fatal(String message) { } public static void fatal(String message, Throwable t) { - fatal(String.format("%s\n%s\n%s", message, t.getMessage(), Throwables.getStackTrace(t))); - + fatal(String.format("%s\n%s\n%s", message, t.getMessage(), Util.stacktraceFrom(t))); } private static void logToStdout(String level, String message) { - System.out.println(getJsonObject(level, message)); + System.out.println(LogMessage.of(level, message)); } - private static JSONObject getJsonObject(String level, String message) { - JSONObject jsonObj = new JSONObject(); - jsonObj.put("logLevel", level); - jsonObj.put("message", message); - return jsonObj; + private static void logToStdErr(String level, String message) { + System.err.println(LogMessage.of(level, message)); } - private static void logToStdErr(String level, String message) { - System.err.println(getJsonObject(level, message)); + private record LogMessage(@Expose @SerializedName("logLevel") String level, @Expose @SerializedName("message") String message) { + private static final Gson GSON = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); + + public static LogMessage of(String level, String message) { + return new LogMessage(level, message); + } + + @Override + public String toString() { + return GSON.toJson(this); + } } } diff --git a/src/main/java/com/thoughtworks/gauge/Table.java b/src/main/java/com/thoughtworks/gauge/Table.java index ac81b1b9..85b4ec56 100644 --- a/src/main/java/com/thoughtworks/gauge/Table.java +++ b/src/main/java/com/thoughtworks/gauge/Table.java @@ -5,10 +5,8 @@ *----------------------------------------------------------------*/ package com.thoughtworks.gauge; -import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Strings; -import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.Collections; @@ -25,14 +23,13 @@ public class Table { private static final String DASH = "-"; private static final String PIPE = "|"; private static final char SPACE_AS_CHAR = ' '; + private final List headers; - private final List> rows; - private final List tableRows; + private final List> rows = new ArrayList<>(); + private final List tableRows = new ArrayList<>(); public Table(List headers) { this.headers = headers; - rows = new ArrayList<>(); - tableRows = new ArrayList<>(); } public void addRow(List row) { @@ -57,7 +54,7 @@ public List getColumnNames() { /** * Gets a Column name by index. * - * @param columnIndex + * @param columnIndex 0-indexed column ordinal within the table * @return a single column name by given column index. */ public String getColumnName(int columnIndex) { @@ -74,16 +71,6 @@ public List getTableRows() { return tableRows; } - /** - * @return List of TableRows in the table. Each Row is represented by a List - * of String values according to the order of column names - * @deprecated Use getTableRows() method instead of this. - */ - @Deprecated - public List> getRows() { - return rows; - } - /** * Get all the values of a column in Table. * @@ -144,14 +131,10 @@ private void addValues(int maxStringLength, List formattedHeaderAndRows) } private String formattedRow(List strings, int maxStringLength) { - List formattedStrings = Lists.transform(strings, format(maxStringLength)); + List formattedStrings = strings.stream().map(s -> Strings.padEnd(s, maxStringLength, SPACE_AS_CHAR)).toList(); return PIPE + Joiner.on(PIPE).join(formattedStrings) + PIPE; } - private Function format(final int maxStringLength) { - return input -> Strings.padEnd(input, maxStringLength, SPACE_AS_CHAR); - } - private Integer getMaxStringLength() { List maxs = new ArrayList<>(); maxs.add(getMaxStringSize(headers)); @@ -177,8 +160,8 @@ public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (headers == null ? 0 : headers.hashCode()); - result = prime * result + (rows == null ? 0 : rows.hashCode()); - result = prime * result + (tableRows == null ? 0 : tableRows.hashCode()); + result = prime * result + rows.hashCode(); + result = prime * result + tableRows.hashCode(); return result; } diff --git a/src/main/java/com/thoughtworks/gauge/Util.java b/src/main/java/com/thoughtworks/gauge/Util.java index 60040097..b5da09c6 100644 --- a/src/main/java/com/thoughtworks/gauge/Util.java +++ b/src/main/java/com/thoughtworks/gauge/Util.java @@ -8,6 +8,8 @@ import com.google.common.base.Splitter; import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -60,4 +62,12 @@ public static boolean shouldTakeFailureScreenshot() { return !(screenshotOnFailureEnabled == null || "false".equalsIgnoreCase(screenshotOnFailureEnabled)); } + public static String stacktraceFrom(Throwable throwable) { + StringWriter sw = new StringWriter(); + try (PrintWriter pw = new PrintWriter(sw, true)) { + throwable.printStackTrace(pw); + return sw.getBuffer().toString(); + } + } + } diff --git a/src/main/java/com/thoughtworks/gauge/datastore/DataStore.java b/src/main/java/com/thoughtworks/gauge/datastore/DataStore.java deleted file mode 100644 index b9c870fa..00000000 --- a/src/main/java/com/thoughtworks/gauge/datastore/DataStore.java +++ /dev/null @@ -1,55 +0,0 @@ -/*---------------------------------------------------------------- - * Copyright (c) ThoughtWorks, Inc. - * Licensed under the Apache License, Version 2.0 - * See LICENSE.txt in the project root for license information. - *----------------------------------------------------------------*/ -package com.thoughtworks.gauge.datastore; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -/** - * @deprecated DataStore is no longer valid. The usage together with DataStoreFactory API will throw an Exception in multithreaded execution. - *

Use specific data stores instead.

- * @see com.thoughtworks.gauge.datastore.SuiteDataStore - * @see com.thoughtworks.gauge.datastore.SpecDataStore - * @see com.thoughtworks.gauge.datastore.ScenarioDataStore - */ -@Deprecated -public class DataStore { - - private final HashMap map = new HashMap<>(); - - /** - * @param key - Key of the data entry - * @param value - value of the Data entry - */ - public void put(Object key, Object value) { - map.put(key, value); - } - - /** - * @param key - Key of the data entry to remove - * @return The value of the entry removed. Null if no entry. - */ - public Object remove(Object key) { - return map.remove(key); - } - - /** - * @param key - Key of the data entry whose value is needed - * @return The value corresponding to the key. null if there is no value stored - */ - public Object get(Object key) { - return map.get(key); - } - - void clear() { - map.clear(); - } - - public Set> entrySet() { - return map.entrySet(); - } - -} diff --git a/src/main/java/com/thoughtworks/gauge/datastore/DataStoreFactory.java b/src/main/java/com/thoughtworks/gauge/datastore/DataStoreFactory.java deleted file mode 100644 index 4038ed55..00000000 --- a/src/main/java/com/thoughtworks/gauge/datastore/DataStoreFactory.java +++ /dev/null @@ -1,87 +0,0 @@ -/*---------------------------------------------------------------- - * Copyright (c) ThoughtWorks, Inc. - * Licensed under the Apache License, Version 2.0 - * See LICENSE.txt in the project root for license information. - *----------------------------------------------------------------*/ -package com.thoughtworks.gauge.datastore; - -import static com.thoughtworks.gauge.GaugeConstant.ENABLE_MULTITHREADING_ENV; - - -/** - * @deprecated DataStoreFactory is no longer valid. This API will throw an Exception in multithreaded execution. - *

Use specific data stores instead.

- * @see com.thoughtworks.gauge.datastore.SuiteDataStore - * @see com.thoughtworks.gauge.datastore.SpecDataStore - * @see com.thoughtworks.gauge.datastore.ScenarioDataStore - */ -@Deprecated -public class DataStoreFactory { - private static final ThreadLocal SUITE_DATA_STORE = new InheritableThreadLocal<>() { - @Override - protected DataStore initialValue() { - return new DataStore(); - } - }; - private static final ThreadLocal SPEC_DATA_STORE = new InheritableThreadLocal<>() { - @Override - protected DataStore initialValue() { - return new DataStore(); - } - }; - private static final ThreadLocal SCENARIO_DATA_STORE = new InheritableThreadLocal<>() { - @Override - protected DataStore initialValue() { - return new DataStore(); - } - }; - - - /** - * @return The current instance of the SuiteDataStore - */ - public static DataStore getSuiteDataStore() { - if (isMultithreadingExecution()) { - throw new RuntimeException("DataStoreFactory cannot be used for multithreaded execution. Use SuiteDataStore."); - } - return SUITE_DATA_STORE.get(); - } - - /** - * @return The current instance of the SpecDataStore - */ - public static DataStore getSpecDataStore() { - if (isMultithreadingExecution()) { - throw new RuntimeException("DataStoreFactory cannot be used for multithreaded execution. Use SpecDataStore."); - } - return SPEC_DATA_STORE.get(); - } - - - /** - * @return The current instance of the ScenarioDataStore - */ - public static DataStore getScenarioDataStore() { - if (isMultithreadingExecution()) { - throw new RuntimeException("DataStoreFactory cannot be used for multithreaded execution. Use ScenarioDataStore."); - } - return SCENARIO_DATA_STORE.get(); - } - - static void clearSuiteDataStore() { - SUITE_DATA_STORE.get().clear(); - } - - static void clearSpecDataStore() { - SPEC_DATA_STORE.get().clear(); - } - - static void clearScenarioDataStore() { - SCENARIO_DATA_STORE.get().clear(); - } - - private static boolean isMultithreadingExecution() { - return Boolean.parseBoolean(System.getenv(ENABLE_MULTITHREADING_ENV)); - } - -} diff --git a/src/main/java/com/thoughtworks/gauge/datastore/DataStoreInitializer.java b/src/main/java/com/thoughtworks/gauge/datastore/DataStoreInitializer.java index 46fd95d1..ab2aee3b 100644 --- a/src/main/java/com/thoughtworks/gauge/datastore/DataStoreInitializer.java +++ b/src/main/java/com/thoughtworks/gauge/datastore/DataStoreInitializer.java @@ -16,15 +16,12 @@ public class DataStoreInitializer implements IMessageProcessor { public Messages.Message process(Messages.Message message) { switch (message.getMessageType()) { // SUPPRESS CHECKSTYLE case SuiteDataStoreInit: - DataStoreFactory.clearSuiteDataStore(); SuiteDataStore.clear(); break; case SpecDataStoreInit: - DataStoreFactory.clearSpecDataStore(); SpecDataStore.clear(); break; case ScenarioDataStoreInit: - DataStoreFactory.clearScenarioDataStore(); ScenarioDataStore.clear(); break; } diff --git a/src/main/java/com/thoughtworks/gauge/processor/ExecuteStepProcessor.java b/src/main/java/com/thoughtworks/gauge/processor/ExecuteStepProcessor.java index e3b8245d..feea285f 100644 --- a/src/main/java/com/thoughtworks/gauge/processor/ExecuteStepProcessor.java +++ b/src/main/java/com/thoughtworks/gauge/processor/ExecuteStepProcessor.java @@ -10,10 +10,8 @@ import com.thoughtworks.gauge.MessageCollector; import com.thoughtworks.gauge.ScreenshotCollector; import com.thoughtworks.gauge.execution.ExecutionPipeline; -import com.thoughtworks.gauge.execution.HookExecutionStage; import com.thoughtworks.gauge.execution.StepExecutionStage; import com.thoughtworks.gauge.execution.parameters.parsers.base.ParameterParsingChain; -import com.thoughtworks.gauge.registry.HooksRegistry; import com.thoughtworks.gauge.registry.StepRegistry; import gauge.messages.Messages; import gauge.messages.Spec; @@ -38,9 +36,7 @@ public Messages.Message process(Messages.Message message) { Logger.fatal("No step definition found. Try compiling the source before execution."); } Logger.debug("Executing '" + stepText + "' using '" + method.getDeclaringClass() + "." + method.getName()); - ExecutionPipeline pipeline = new ExecutionPipeline(new HookExecutionStage(HooksRegistry.getBeforeClassStepsHooksOfClass(method.getDeclaringClass()), getInstanceManager())); - pipeline.addStages(new StepExecutionStage(message.getExecuteStepRequest(), getInstanceManager(), chain, registry), - new HookExecutionStage(HooksRegistry.getAfterClassStepsHooksOfClass(method.getDeclaringClass()), getInstanceManager())); + ExecutionPipeline pipeline = new ExecutionPipeline(new StepExecutionStage(message.getExecuteStepRequest(), getInstanceManager(), chain, registry)); Spec.ProtoExecutionResult executionResult = pipeline.start(); Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); diff --git a/src/main/java/com/thoughtworks/gauge/registry/HooksRegistry.java b/src/main/java/com/thoughtworks/gauge/registry/HooksRegistry.java index 2a2bd6eb..fb455e59 100644 --- a/src/main/java/com/thoughtworks/gauge/registry/HooksRegistry.java +++ b/src/main/java/com/thoughtworks/gauge/registry/HooksRegistry.java @@ -12,7 +12,6 @@ import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; import static java.util.stream.Collectors.toList; @@ -95,26 +94,6 @@ public static void addAfterSuiteHooks(Set methods) { addHooks(methods, AfterSuite.class); } - public static void addAfterClassStepsHooks(Set methods) { - addHooksWithTags(methods, AfterClassSteps.class); - } - - public static void addBeforeClassStepsHooks(Set methods) { - addHooksWithTags(methods, BeforeClassSteps.class); - } - - public static List getBeforeClassStepsHooksOfClass(Class aClass) { - return sort(findClassHooksForClass(getBeforeClassHooks(), aClass)); - } - - public static List getAfterClassStepsHooksOfClass(Class aClass) { - return sortReverse(findClassHooksForClass(getAfterClassHooks(), aClass)); - } - - private static Set findClassHooksForClass(List allClassHooks, Class aClass) { - return allClassHooks.stream().filter(hook -> hook.getMethod().getDeclaringClass().equals(aClass)).collect(Collectors.toSet()); - } - private static void addHooks(Set methods, Class hookClass) { REGISTRY_MAP.putIfAbsent(hookClass, new HashSet<>()); REGISTRY_MAP.get(hookClass).addAll(methods.stream().map(Hook::new).toList()); @@ -135,14 +114,6 @@ private static void addHooksWithTags(Set methods, Class getBeforeClassHooks() { - return sort(REGISTRY_MAP.get(BeforeClassSteps.class)); - } - - private static List getAfterClassHooks() { - return sortReverse(REGISTRY_MAP.get(AfterClassSteps.class)); - } - static void remove(Class hookType) { REGISTRY_MAP.remove(hookType); } diff --git a/src/main/java/com/thoughtworks/gauge/scan/HooksScanner.java b/src/main/java/com/thoughtworks/gauge/scan/HooksScanner.java index ec9a999d..feaa6cbb 100644 --- a/src/main/java/com/thoughtworks/gauge/scan/HooksScanner.java +++ b/src/main/java/com/thoughtworks/gauge/scan/HooksScanner.java @@ -5,17 +5,7 @@ *----------------------------------------------------------------*/ package com.thoughtworks.gauge.scan; -import com.thoughtworks.gauge.AfterClassSteps; -import com.thoughtworks.gauge.AfterScenario; -import com.thoughtworks.gauge.AfterSpec; -import com.thoughtworks.gauge.AfterStep; -import com.thoughtworks.gauge.AfterSuite; -import com.thoughtworks.gauge.BeforeClassSteps; -import com.thoughtworks.gauge.BeforeScenario; -import com.thoughtworks.gauge.BeforeSpec; -import com.thoughtworks.gauge.BeforeStep; -import com.thoughtworks.gauge.BeforeSuite; -import com.thoughtworks.gauge.Logger; +import com.thoughtworks.gauge.*; import com.thoughtworks.gauge.registry.HooksRegistry; import org.reflections.Reflections; @@ -38,7 +28,5 @@ private void buildHooksRegistry(Reflections reflections) { HooksRegistry.addAfterScenarioHooks(reflections.getMethodsAnnotatedWith(AfterScenario.class)); HooksRegistry.addBeforeStepHooks(reflections.getMethodsAnnotatedWith(BeforeStep.class)); HooksRegistry.setAfterStepHooks(reflections.getMethodsAnnotatedWith(AfterStep.class)); - HooksRegistry.addBeforeClassStepsHooks(reflections.getMethodsAnnotatedWith(BeforeClassSteps.class)); - HooksRegistry.addAfterClassStepsHooks(reflections.getMethodsAnnotatedWith(AfterClassSteps.class)); } } diff --git a/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshot.java b/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshot.java deleted file mode 100644 index 4947092e..00000000 --- a/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshot.java +++ /dev/null @@ -1,9 +0,0 @@ -/*---------------------------------------------------------------- - * Copyright (c) ThoughtWorks, Inc. - * Licensed under the Apache License, Version 2.0 - * See LICENSE.txt in the project root for license information. - *----------------------------------------------------------------*/ -package com.thoughtworks.gauge.screenshot; - -interface CustomScreenshot { -} diff --git a/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotScanner.java b/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotScanner.java index 4faae093..87fb3147 100644 --- a/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotScanner.java +++ b/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotScanner.java @@ -16,17 +16,9 @@ */ public class CustomScreenshotScanner implements IScanner { public void scan(Reflections reflections) { - Set> customScreenshotGrabbers = reflections.getSubTypesOf(ICustomScreenshotGrabber.class); - - if (customScreenshotGrabbers.size() > 0) { - Class customScreenGrabber = customScreenshotGrabbers.iterator().next(); - Logger.debug(String.format("Using %s as custom screenshot grabber", customScreenGrabber.getName())); - ScreenshotFactory.setCustomScreenshotGrabber(customScreenGrabber); - } - Set> customScreenshotWriters = reflections.getSubTypesOf(CustomScreenshotWriter.class); - if (customScreenshotWriters.size() > 0) { + if (!customScreenshotWriters.isEmpty()) { Class customScreenWriter = customScreenshotWriters.iterator().next(); Logger.debug(String.format("Using %s as custom screenshot grabber", customScreenWriter.getName())); ScreenshotFactory.setCustomScreenshotGrabber(customScreenWriter); diff --git a/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotWriter.java b/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotWriter.java index 324636f1..41cf5d79 100644 --- a/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotWriter.java +++ b/src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotWriter.java @@ -12,7 +12,7 @@ * Implementation of this interface should capture screenshot and write them into a unique file * inside screenshots directory. Use "gauge_screenshots_dir" env to get screenshot directory path" */ -public interface CustomScreenshotWriter extends CustomScreenshot { +public interface CustomScreenshotWriter { /** * @return Name of the screenshot file taken. diff --git a/src/main/java/com/thoughtworks/gauge/screenshot/ICustomScreenshotGrabber.java b/src/main/java/com/thoughtworks/gauge/screenshot/ICustomScreenshotGrabber.java deleted file mode 100644 index b7cc5714..00000000 --- a/src/main/java/com/thoughtworks/gauge/screenshot/ICustomScreenshotGrabber.java +++ /dev/null @@ -1,23 +0,0 @@ -/*---------------------------------------------------------------- - * Copyright (c) ThoughtWorks, Inc. - * Licensed under the Apache License, Version 2.0 - * See LICENSE.txt in the project root for license information. - *----------------------------------------------------------------*/ -package com.thoughtworks.gauge.screenshot; - -/** - * Implement this interface to take Custom Screenshots on Failure. It overrides the default screenshot taking mechanism. - * The captured screenshots can be seen on the reports on failure. - * If multiple implementations are found, one will be picked randomly to capture screenshots. - */ -@Deprecated -public interface ICustomScreenshotGrabber extends CustomScreenshot { - - - /** - * @return Byte array of the screenshot taken. - * Return an empty Byte array if unable to capture screen. - */ - byte[] takeScreenshot(); - -} diff --git a/src/main/java/com/thoughtworks/gauge/screenshot/ScreenshotFactory.java b/src/main/java/com/thoughtworks/gauge/screenshot/ScreenshotFactory.java index 6d871c7d..43dfa42f 100644 --- a/src/main/java/com/thoughtworks/gauge/screenshot/ScreenshotFactory.java +++ b/src/main/java/com/thoughtworks/gauge/screenshot/ScreenshotFactory.java @@ -12,7 +12,6 @@ import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; import java.io.File; import java.nio.file.Path; import java.util.UUID; @@ -21,17 +20,17 @@ * Used to take screenshots on failure. */ public class ScreenshotFactory { - public static final String IMAGE_EXTENSION = "png"; - private static Class customScreenshotGrabber; + private static volatile Class customScreenshotWriter; + private final ClassInstanceManager manager; public ScreenshotFactory(ClassInstanceManager manager) { this.manager = manager; } - static void setCustomScreenshotGrabber(Class customScreenGrabber) { - customScreenshotGrabber = customScreenGrabber; + static void setCustomScreenshotGrabber(Class writerClass) { + ScreenshotFactory.customScreenshotWriter = writerClass; } public String getScreenshotBytes() { @@ -39,21 +38,13 @@ public String getScreenshotBytes() { } private String takeScreenshot() { - if (customScreenshotGrabber != null) { + if (customScreenshotWriter != null) { try { - CustomScreenshot customScreenInstance = (CustomScreenshot) manager.get(customScreenshotGrabber); - if (customScreenInstance instanceof CustomScreenshotWriter writer) { - return writer.takeScreenshot(); - } else { - byte[] bytes = ((ICustomScreenshotGrabber) customScreenInstance).takeScreenshot(); - File file = generateUniqueScreenshotFile(); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); - BufferedImage bufferedImage = ImageIO.read(byteArrayInputStream); - ImageIO.write(bufferedImage, IMAGE_EXTENSION, file); - return file.getName(); + if (manager.get(customScreenshotWriter) instanceof CustomScreenshotWriter writer) { + return writer.takeScreenshot(); } } catch (Exception e) { - Logger.error(String.format("Failed to take Custom screenshot: %s : %s", customScreenshotGrabber.getCanonicalName(), e.getMessage())); + Logger.error(String.format("Failed to take Custom screenshot: %s : %s", customScreenshotWriter.getCanonicalName(), e.getMessage())); Logger.warning("Capturing regular screenshot.."); } } diff --git a/src/test/java/com/thoughtworks/gauge/registry/HooksRegistryTest.java b/src/test/java/com/thoughtworks/gauge/registry/HooksRegistryTest.java index ef992626..9f6bda81 100644 --- a/src/test/java/com/thoughtworks/gauge/registry/HooksRegistryTest.java +++ b/src/test/java/com/thoughtworks/gauge/registry/HooksRegistryTest.java @@ -13,7 +13,6 @@ import java.lang.reflect.Method; import java.util.HashSet; import java.util.List; -import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -99,26 +98,6 @@ public void testAddingBeforeAndAfterStepHooks() throws Exception { assertEquals(Operator.OR, ((Hook) afterStepHooks.toArray()[0]).getTagsAggregation()); } - @Test - public void testAddingBeforeAndAfterClassStepHooks() throws Exception { - Method beforeClassSteps1 = TestHooksImplClass.class.getMethod("beforeClassSteps1"); - Method beforeClassSteps2 = TestHooksImplClass.class.getMethod("beforeClassSteps2"); - Method afterClassSteps = TestHooksImplClass.class.getMethod("afterClassSteps"); - HooksRegistry.addBeforeClassStepsHooks(createSet(beforeClassSteps1, beforeClassSteps2)); - HooksRegistry.addAfterClassStepsHooks(createSet(afterClassSteps)); - - List beforeHooks = HooksRegistry.getBeforeClassStepsHooksOfClass(TestHooksImplClass.class); - assertEquals(2, beforeHooks.size()); - Set beforeMethods = hooksMethodList(beforeHooks); - assertTrue(beforeMethods.contains(beforeClassSteps1)); - assertTrue(beforeMethods.contains(beforeClassSteps2)); - - List afterHooks = HooksRegistry.getAfterClassStepsHooksOfClass(TestHooksImplClass.class); - Set afterHookMethods = hooksMethodList(afterHooks); - assertEquals(1, afterHooks.size()); - assertTrue(afterHookMethods.contains(afterClassSteps)); - } - @Test public void testSortingOfPreHooks() throws NoSuchMethodException { Method beforeScenario = TestHooksImplClass.class.getMethod("beforeScenario"); @@ -147,14 +126,6 @@ public void testSortingOfPostHooks() throws NoSuchMethodException { assertEquals("afterScenario", sortedPostHooks.get(2).getMethod().getName()); } - private Set hooksMethodList(List hooks) { - HashSet methods = new HashSet<>(); - for (Hook hook : hooks) { - methods.add(hook.getMethod()); - } - return methods; - } - @AfterEach protected void tearDown() throws Exception { HooksRegistry.remove(BeforeStep.class); @@ -165,8 +136,6 @@ protected void tearDown() throws Exception { HooksRegistry.remove(AfterSuite.class); HooksRegistry.remove(BeforeSpec.class); HooksRegistry.remove(AfterSpec.class); - HooksRegistry.remove(AfterClassSteps.class); - HooksRegistry.remove(BeforeClassSteps.class); } private HashSet createSet(Method... methods) { @@ -238,21 +207,6 @@ public void beforeSuite() { public void afterSuite() { } - - @BeforeClassSteps(tags = {"tag1", "tag2"}) - public void beforeClassSteps1() { - - } - - @BeforeClassSteps - public void beforeClassSteps2() { - - } - - @AfterClassSteps(tags = {"tag3", "tag4"}, tagAggregation = Operator.OR) - public void afterClassSteps() { - - } } }