diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f56f33..b88eb93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +### Changed +- Client version updated on [5.2.0](https://github.com/reportportal/client-java/releases/tag/5.2.0), by @HardNorth ## [5.1.5] ### Changed diff --git a/build.gradle b/build.gradle index c9bd215..dc0996e 100644 --- a/build.gradle +++ b/build.gradle @@ -37,11 +37,12 @@ repositories { } dependencies { - api 'com.epam.reportportal:client-java:5.1.22' + api 'com.epam.reportportal:client-java:5.2.0' api 'com.epam.reportportal:commons-model:5.0.0' api 'com.google.code.findbugs:jsr305:3.0.2' api "io.cucumber:cucumber-java:${project.cucumber_version}" + implementation 'com.squareup.okhttp3:okhttp:4.12.0' implementation 'org.slf4j:slf4j-api:2.0.7' testImplementation 'com.epam.reportportal:agent-java-test-utils:0.0.2' @@ -51,8 +52,8 @@ dependencies { testImplementation 'org.hamcrest:hamcrest-core:2.2' testImplementation 'org.mockito:mockito-core:3.3.3' testImplementation 'org.mockito:mockito-junit-jupiter:3.3.3' - testImplementation 'ch.qos.logback:logback-classic:1.3.8' - testImplementation 'com.epam.reportportal:logger-java-logback:5.1.5' + testImplementation 'ch.qos.logback:logback-classic:1.3.12' + testImplementation 'com.epam.reportportal:logger-java-logback:5.2.0' testImplementation ("org.junit.platform:junit-platform-runner:${project.junit_runner_version}") { exclude module: 'junit' } diff --git a/gradle.properties b/gradle.properties index 8660089..dde944b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=5.1.6-SNAPSHOT +version=5.2.0-SNAPSHOT description=EPAM Report portal. Cucumber version 2 integration cucumber_version=2.4.0 junit_version=5.6.3 diff --git a/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java b/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java index e5bc548..dae7931 100644 --- a/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java +++ b/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java @@ -18,6 +18,7 @@ import com.epam.reportportal.annotations.TestCaseId; import com.epam.reportportal.annotations.attribute.Attributes; import com.epam.reportportal.listeners.ItemStatus; +import com.epam.reportportal.listeners.ItemType; import com.epam.reportportal.listeners.ListenerParameters; import com.epam.reportportal.message.ReportPortalMessage; import com.epam.reportportal.service.Launch; @@ -25,6 +26,8 @@ import com.epam.reportportal.service.item.TestCaseIdEntry; import com.epam.reportportal.service.tree.TestItemTree; import com.epam.reportportal.utils.*; +import com.epam.reportportal.utils.files.ByteSource; +import com.epam.reportportal.utils.markdown.MarkdownUtils; import com.epam.reportportal.utils.properties.SystemAttributesExtractor; import com.epam.ta.reportportal.ws.model.FinishExecutionRQ; import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; @@ -32,14 +35,12 @@ import com.epam.ta.reportportal.ws.model.StartTestItemRQ; import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ; import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; -import com.google.common.io.ByteSource; import cucumber.api.HookType; import cucumber.api.Result; import cucumber.api.TestCase; import cucumber.api.TestStep; import cucumber.api.event.*; import cucumber.api.formatter.Formatter; -import cucumber.runtime.StepDefinitionMatch; import gherkin.ast.Feature; import gherkin.ast.Step; import gherkin.ast.Tag; @@ -705,6 +706,7 @@ protected void finishFeature(Maybe itemId, Date dateTime) { LOGGER.error("BUG: Trying to finish unspecified test item."); return; } + //noinspection ReactiveStreamsUnusedPublisher launch.get().finishTestItem(itemId, buildFinishTestItemRequest(itemId, dateTime, null)); } @@ -744,6 +746,7 @@ protected Date finishTestItem(@Nullable Maybe itemId, @Nullable Result.T } FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, null, mapItemStatus(status)); + //noinspection ReactiveStreamsUnusedPublisher launch.get().finishTestItem(itemId, rq); return rq.getEndTime(); } @@ -796,7 +799,7 @@ protected String buildMultilineArgument(@Nonnull TestStep step) { StringBuilder marg = new StringBuilder(); if (table != null) { - marg.append(formatDataTable(table)); + marg.append(MarkdownUtils.formatDataTable(table)); } if (docString != null) { @@ -841,10 +844,10 @@ protected Set extractAttributes(List tags) { */ @Nullable protected Set getAttributes(@Nonnull TestStep testStep) { - Field definitionMatchField = getDefinitionMatchField(testStep); - if (definitionMatchField != null) { + Object definitionMatch = getDefinitionMatch(testStep); + if (definitionMatch != null) { try { - Method method = retrieveMethod(definitionMatchField, testStep); + Method method = retrieveMethod(definitionMatch); Attributes attributesAnnotation = method.getAnnotation(Attributes.class); if (attributesAnnotation != null) { return AttributeParser.retrieveAttributes(attributesAnnotation); @@ -864,9 +867,8 @@ protected Set getAttributes(@Nonnull TestStep testStep) { */ @Nullable protected String getCodeRef(@Nonnull TestStep testStep) { - return ofNullable(getDefinitionMatchField(testStep)).flatMap(match -> { + return ofNullable(getDefinitionMatch(testStep)).flatMap(stepDefinitionMatch -> { try { - StepDefinitionMatch stepDefinitionMatch = (StepDefinitionMatch) match.get(testStep); Field stepDefinitionField = stepDefinitionMatch.getClass().getDeclaredField(STEP_DEFINITION_FIELD_NAME); stepDefinitionField.setAccessible(true); Object javaStepDefinition = stepDefinitionField.get(stepDefinitionMatch); @@ -908,10 +910,10 @@ protected String getCodeRef(@Nonnull String uri, int line) { @Nullable @SuppressWarnings("unchecked") protected TestCaseIdEntry getTestCaseId(@Nonnull TestStep testStep, @Nullable String codeRef) { - Field definitionMatchField = getDefinitionMatchField(testStep); - if (definitionMatchField != null) { + Object definitionMatch = getDefinitionMatch(testStep); + if (definitionMatch != null) { try { - Method method = retrieveMethod(definitionMatchField, testStep); + Method method = retrieveMethod(definitionMatch); return TestCaseIdUtils.getTestCaseId(method.getAnnotation(TestCaseId.class), method, codeRef, @@ -954,7 +956,7 @@ protected List getParameters(@Nullable String codeRef, @Nonnu if (arg instanceof PickleString) { value = ((PickleString) arg).getContent(); } else if (arg instanceof PickleTable) { - value = formatDataTable(((PickleTable) arg).getRows() + value = MarkdownUtils.formatDataTable(((PickleTable) arg).getRows() .stream() .map(r -> r.getCells().stream().map(PickleCell::getValue).collect(Collectors.toList())) .collect(Collectors.toList())); @@ -1000,18 +1002,13 @@ protected String getDescription(@Nonnull Feature feature, @Nonnull String uri) { */ @Nonnull protected Pair getHookTypeAndName(@Nonnull HookType hookType) { - String name = null; - String type = null; switch (hookType) { case Before: - name = "Before hooks"; - type = "BEFORE_TEST"; - break; + return Pair.of(ItemType.BEFORE_TEST.name(), "Before hooks"); case After: - name = "After hooks"; - type = "AFTER_TEST"; - break; + return Pair.of(ItemType.AFTER_TEST.name(), "After hooks"); + default: + return Pair.of(ItemType.TEST.name(), "Hook"); } - return Pair.of(type, name); } } diff --git a/src/main/java/com/epam/reportportal/cucumber/ScenarioReporter.java b/src/main/java/com/epam/reportportal/cucumber/ScenarioReporter.java index 1cb7e3c..19e9a97 100644 --- a/src/main/java/com/epam/reportportal/cucumber/ScenarioReporter.java +++ b/src/main/java/com/epam/reportportal/cucumber/ScenarioReporter.java @@ -15,6 +15,7 @@ */ package com.epam.reportportal.cucumber; +import com.epam.reportportal.listeners.ItemType; import com.epam.reportportal.utils.MemoizingSupplier; import com.epam.ta.reportportal.ws.model.StartTestItemRQ; import cucumber.api.HookType; @@ -46,9 +47,9 @@ * @author Serhii Zharskyi */ public class ScenarioReporter extends AbstractReporter { - private static final String RP_STORY_TYPE = "SUITE"; - private static final String RP_TEST_TYPE = "STORY"; - private static final String RP_STEP_TYPE = "STEP"; + private static final String RP_STORY_TYPE = ItemType.SUITE.name(); + private static final String RP_TEST_TYPE = ItemType.STORY.name(); + private static final String RP_STEP_TYPE = ItemType.STEP.name(); protected MemoizingSupplier> rootSuiteId; diff --git a/src/main/java/com/epam/reportportal/cucumber/StepReporter.java b/src/main/java/com/epam/reportportal/cucumber/StepReporter.java index 4e81eff..a4e5e58 100644 --- a/src/main/java/com/epam/reportportal/cucumber/StepReporter.java +++ b/src/main/java/com/epam/reportportal/cucumber/StepReporter.java @@ -15,6 +15,7 @@ */ package com.epam.reportportal.cucumber; +import com.epam.reportportal.listeners.ItemType; import io.reactivex.Maybe; import javax.annotation.Nonnull; @@ -36,12 +37,12 @@ * created in hooks will be attached to these, and not to the actual failing * steps!) * - * @author Sergey_Gvozdyukevich - * @author Serhii Zharskyi + * @deprecated Use {@link ScenarioReporter}, since the semantic of this class is completely broken and will be removed */ +@Deprecated public class StepReporter extends AbstractReporter { - private static final String RP_STORY_TYPE = "STORY"; - private static final String RP_TEST_TYPE = "SCENARIO"; + private static final String RP_STORY_TYPE = ItemType.STORY.name(); + private static final String RP_TEST_TYPE = ItemType.SCENARIO.name(); @Override @Nonnull diff --git a/src/main/java/com/epam/reportportal/cucumber/Utils.java b/src/main/java/com/epam/reportportal/cucumber/Utils.java index 22f61df..d95694f 100644 --- a/src/main/java/com/epam/reportportal/cucumber/Utils.java +++ b/src/main/java/com/epam/reportportal/cucumber/Utils.java @@ -16,20 +16,16 @@ package com.epam.reportportal.cucumber; import com.epam.reportportal.listeners.ItemStatus; -import com.google.common.collect.ImmutableMap; +import com.epam.reportportal.listeners.LogLevel; +import com.epam.reportportal.utils.reflect.Accessible; import cucumber.api.Result; import cucumber.api.TestStep; -import cucumber.runtime.StepDefinitionMatch; import io.reactivex.annotations.Nullable; import javax.annotation.Nonnull; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; -import java.util.stream.IntStream; import static java.util.Optional.ofNullable; @@ -37,31 +33,29 @@ public class Utils { private static final String DEFINITION_MATCH_FIELD_NAME = "definitionMatch"; private static final String STEP_DEFINITION_FIELD_NAME = "stepDefinition"; private static final String METHOD_FIELD_NAME = "method"; - public static final String ONE_SPACE = "\u00A0"; - private static final String NEW_LINE = "\r\n"; - public static final String TABLE_INDENT = "\u00A0\u00A0\u00A0\u00A0"; - public static final String TABLE_COLUMN_SEPARATOR = "|"; - public static final String TABLE_ROW_SEPARATOR = "-"; private Utils() { + throw new RuntimeException("No instances should exist for the class!"); } //@formatter:off - public static final Map STATUS_MAPPING = ImmutableMap.builder() - .put(Result.Type.PASSED, ItemStatus.PASSED) - .put(Result.Type.FAILED, ItemStatus.FAILED) - .put(Result.Type.SKIPPED, ItemStatus.SKIPPED) - .put(Result.Type.PENDING, ItemStatus.SKIPPED) - .put(Result.Type.UNDEFINED, ItemStatus.SKIPPED) - .put(Result.Type.AMBIGUOUS, ItemStatus.SKIPPED).build(); - - public static final Map LOG_LEVEL_MAPPING = ImmutableMap.builder() - .put(Result.Type.PASSED, "INFO") - .put(Result.Type.FAILED, "ERROR") - .put(Result.Type.SKIPPED, "WARN") - .put(Result.Type.PENDING, "WARN") - .put(Result.Type.UNDEFINED, "WARN") - .put(Result.Type.AMBIGUOUS, "WARN").build(); + public static final Map STATUS_MAPPING = Collections.unmodifiableMap(new HashMap(){{ + put(Result.Type.PASSED, ItemStatus.PASSED); + put(Result.Type.FAILED, ItemStatus.FAILED); + put(Result.Type.SKIPPED, ItemStatus.SKIPPED); + put(Result.Type.PENDING, ItemStatus.SKIPPED); + put(Result.Type.UNDEFINED, ItemStatus.SKIPPED); + put(Result.Type.AMBIGUOUS, ItemStatus.SKIPPED); + }}); + + public static final Map LOG_LEVEL_MAPPING = Collections.unmodifiableMap(new HashMap(){{ + put(Result.Type.PASSED, LogLevel.INFO.name()); + put(Result.Type.FAILED, LogLevel.ERROR.name()); + put(Result.Type.SKIPPED, LogLevel.WARN.name()); + put(Result.Type.PENDING, LogLevel.WARN.name()); + put(Result.Type.UNDEFINED, LogLevel.WARN.name()); + put(Result.Type.AMBIGUOUS, LogLevel.WARN.name()); + }}); //@formatter:on /** @@ -76,82 +70,24 @@ public static String buildName(String prefix, String infix, String argument) { return (prefix == null ? "" : prefix) + infix + argument; } - public static Method retrieveMethod(Field definitionMatchField, TestStep testStep) throws NoSuchFieldException, IllegalAccessException { - StepDefinitionMatch stepDefinitionMatch = (StepDefinitionMatch) definitionMatchField.get(testStep); - Field stepDefinitionField = stepDefinitionMatch.getClass().getDeclaredField(STEP_DEFINITION_FIELD_NAME); - stepDefinitionField.setAccessible(true); - Object javaStepDefinition = stepDefinitionField.get(stepDefinitionMatch); - Field methodField = javaStepDefinition.getClass().getDeclaredField(METHOD_FIELD_NAME); - methodField.setAccessible(true); - return (Method) methodField.get(javaStepDefinition); + public static Method retrieveMethod(Object stepDefinitionMatch) throws IllegalAccessException, NoSuchFieldException { + Object javaStepDefinition = Accessible.on(stepDefinitionMatch).field(STEP_DEFINITION_FIELD_NAME).getValue(); + Method method = null; + if (javaStepDefinition != null) { + method = (Method) Accessible.on(javaStepDefinition).field(METHOD_FIELD_NAME).getValue(); + } + return method; } public static final java.util.function.Function, List> ARGUMENTS_TRANSFORM = arguments -> ofNullable( arguments).map(args -> args.stream().map(cucumber.runtime.Argument::getVal).collect(Collectors.toList())).orElse(null); @Nullable - public static Field getDefinitionMatchField(@Nonnull TestStep testStep) { - Class clazz = testStep.getClass(); - + public static Object getDefinitionMatch(@Nonnull TestStep testStep) { try { - return clazz.getField(DEFINITION_MATCH_FIELD_NAME); + return Accessible.on(testStep).field(DEFINITION_MATCH_FIELD_NAME).getValue(); } catch (NoSuchFieldException e) { - do { - try { - Field definitionMatchField = clazz.getDeclaredField(DEFINITION_MATCH_FIELD_NAME); - definitionMatchField.setAccessible(true); - return definitionMatchField; - } catch (NoSuchFieldException ignore) { - } - - clazz = clazz.getSuperclass(); - } while (clazz != null); - return null; } } - - /** - * Converts a table represented as List of Lists to a formatted table string - * - * @param table a table object - * @return string representation of the table - */ - @Nonnull - public static String formatDataTable(@Nonnull final List> table) { - StringBuilder result = new StringBuilder(); - int tableLength = table.stream().mapToInt(List::size).max().orElse(-1); - List> iterList = table.stream().map(List::iterator).collect(Collectors.toList()); - List colSizes = IntStream.range(0, tableLength) - .mapToObj(n -> iterList.stream().filter(Iterator::hasNext).map(Iterator::next).collect(Collectors.toList())) - .map(col -> col.stream().mapToInt(String::length).max().orElse(0)) - .collect(Collectors.toList()); - - boolean header = true; - for (List row : table) { - result.append(TABLE_INDENT).append(TABLE_COLUMN_SEPARATOR); - for (int i = 0; i < row.size(); i++) { - String cell = row.get(i); - int maxSize = colSizes.get(i) - cell.length() + 2; - int lSpace = maxSize / 2; - int rSpace = maxSize - lSpace; - IntStream.range(0, lSpace).forEach(j -> result.append(ONE_SPACE)); - result.append(cell); - IntStream.range(0, rSpace).forEach(j -> result.append(ONE_SPACE)); - result.append(TABLE_COLUMN_SEPARATOR); - } - if (header) { - header = false; - result.append(NEW_LINE); - result.append(TABLE_INDENT).append(TABLE_COLUMN_SEPARATOR); - for (int i = 0; i < row.size(); i++) { - int maxSize = colSizes.get(i) + 2; - IntStream.range(0, maxSize).forEach(j -> result.append(TABLE_ROW_SEPARATOR)); - result.append(TABLE_COLUMN_SEPARATOR); - } - } - result.append(NEW_LINE); - } - return result.toString().trim(); - } } diff --git a/src/test/java/com/epam/reportportal/cucumber/ParameterScenarioReporterTest.java b/src/test/java/com/epam/reportportal/cucumber/ParameterScenarioReporterTest.java index 1f1c09a..b9b7e15 100644 --- a/src/test/java/com/epam/reportportal/cucumber/ParameterScenarioReporterTest.java +++ b/src/test/java/com/epam/reportportal/cucumber/ParameterScenarioReporterTest.java @@ -23,6 +23,7 @@ import com.epam.reportportal.service.ReportPortal; import com.epam.reportportal.service.ReportPortalClient; import com.epam.reportportal.util.test.CommonUtils; +import com.epam.reportportal.utils.markdown.MarkdownUtils; import com.epam.ta.reportportal.ws.model.ParameterResource; import com.epam.ta.reportportal.ws.model.StartTestItemRQ; import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; @@ -73,7 +74,7 @@ public static class DataTableParameterTest extends AbstractTestNGCucumberTests { } private static final String DOCSTRING_PARAM = "My very long parameter\nWith some new lines"; - private static final String TABLE_PARAM = Utils.formatDataTable(Arrays.asList(Arrays.asList("key", "value"), + private static final String TABLE_PARAM = MarkdownUtils.formatDataTable(Arrays.asList(Arrays.asList("key", "value"), Arrays.asList("myKey", "myValue") )); diff --git a/src/test/java/com/epam/reportportal/cucumber/ParameterStepReporterTest.java b/src/test/java/com/epam/reportportal/cucumber/ParameterStepReporterTest.java index c9211af..900c7f8 100644 --- a/src/test/java/com/epam/reportportal/cucumber/ParameterStepReporterTest.java +++ b/src/test/java/com/epam/reportportal/cucumber/ParameterStepReporterTest.java @@ -23,6 +23,7 @@ import com.epam.reportportal.service.ReportPortal; import com.epam.reportportal.service.ReportPortalClient; import com.epam.reportportal.util.test.CommonUtils; +import com.epam.reportportal.utils.markdown.MarkdownUtils; import com.epam.ta.reportportal.ws.model.ParameterResource; import com.epam.ta.reportportal.ws.model.StartTestItemRQ; import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; @@ -88,7 +89,7 @@ public static class DataTableParameterTestStepReporter extends AbstractTestNGCuc } private static final String DOCSTRING_PARAM = "My very long parameter\nWith some new lines"; - private static final String TABLE_PARAM = Utils.formatDataTable(Arrays.asList(Arrays.asList("key", "value"), + private static final String TABLE_PARAM = MarkdownUtils.formatDataTable(Arrays.asList(Arrays.asList("key", "value"), Arrays.asList("myKey", "myValue") ));