diff --git a/CHANGELOG.md b/CHANGELOG.md index 68ec459..1d61f2e 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.4] ### Changed diff --git a/README.md b/README.md index a99f8c6..3a7f4cb 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Reportportal agent for Cucumber v.4 +# ReportPortal agent for Cucumber v.4 -> **DISCLAIMER**: We use Google Analytics for sending anonymous usage information such as agent's and client's names, and their versions -> after a successful launch start. This information might help us to improve both ReportPortal backend and client sides. It is used by the -> ReportPortal team only and is not supposed for sharing with 3rd parties. +> **DISCLAIMER**: We use Google Analytics for sending anonymous usage information such as agent's and client's names, +> and their versions after a successful launch start. This information might help us to improve both ReportPortal +> backend and client sides. It is used by the ReportPortal team only and is not supposed for sharing with 3rd parties. -[![Maven Central](https://img.shields.io/maven-central/v/com.epam.reportportal/agent-java-cucumber4.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.epam.reportportal%22%20AND%20a:%22agent-java-cucumber4%22) +[![Maven Central](https://img.shields.io/maven-central/v/com.epam.reportportal/agent-java-cucumber4.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/com.epam.reportportal/agent-java-cucumber4) [![CI Build](https://github.com/reportportal/agent-java-cucumber4/actions/workflows/ci.yml/badge.svg)](https://github.com/reportportal/agent-java-cucumber4/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/reportportal/agent-java-cucumber4/branch/develop/graph/badge.svg?token=tzVCXKSLP9)](https://codecov.io/gh/reportportal/agent-java-cucumber4) [![Join Slack chat!](https://slack.epmrpp.reportportal.io/badge.svg)](https://slack.epmrpp.reportportal.io/) diff --git a/build.gradle b/build.gradle index 1d2fefb..bc27169 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.1' 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' @@ -50,9 +51,9 @@ 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 'ch.qos.logback:logback-classic:1.3.12' testImplementation "io.cucumber:cucumber-testng:${project.cucumber_version}" - testImplementation 'com.epam.reportportal:logger-java-logback:5.1.5' + 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 0e002bb..46f29e7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=5.1.5-SNAPSHOT +version=5.2.0-SNAPSHOT description=Cucumber JVM version [4.0.0; 5.0.0) adapter cucumber_version=4.8.1 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 857950b..11021ea 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,7 +35,6 @@ 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.*; import cucumber.api.event.*; import cucumber.runtime.StepDefinitionMatch; @@ -155,11 +157,11 @@ protected void afterLaunch() { @Nullable @SuppressWarnings("unchecked") protected TestCaseIdEntry getTestCaseId(@Nonnull TestStep testStep, @Nullable String codeRef) { - Field definitionMatchField = getDefinitionMatchField(testStep); + Object definitionMatch = getDefinitionMatch(testStep); List arguments = ((PickleStepTestStep) testStep).getDefinitionArgument(); - if (definitionMatchField != null) { + if (definitionMatch != null) { try { - Method method = retrieveMethod(definitionMatchField, testStep); + Method method = retrieveMethod((StepDefinitionMatch) definitionMatch); return TestCaseIdUtils.getTestCaseId(method.getAnnotation(TestCaseId.class), method, codeRef, @@ -299,6 +301,7 @@ protected Date finishTestItem(Maybe itemId, Result.Type status) { } FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, null, mapItemStatus(status)); + //noinspection ReactiveStreamsUnusedPublisher launch.get().finishTestItem(itemId, rq); return rq.getEndTime(); } @@ -626,6 +629,7 @@ protected void finishFeature(Maybe itemId, Date dateTime) { return; } FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, dateTime, null); + //noinspection ReactiveStreamsUnusedPublisher launch.get().finishTestItem(itemId, rq); } @@ -833,7 +837,7 @@ protected String mapLevel(@Nullable Result.Type cukesStatus) { */ @Nonnull protected String formatDataTable(@Nonnull final List> table) { - return Utils.formatDataTable(table); + return MarkdownUtils.formatDataTable(table); } /** @@ -905,10 +909,10 @@ protected Set extractAttributes(@Nonnull 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((StepDefinitionMatch) definitionMatch); Attributes attributesAnnotation = method.getAnnotation(Attributes.class); if (attributesAnnotation != null) { return AttributeParser.retrieveAttributes(attributesAnnotation); @@ -928,9 +932,8 @@ protected Set getAttributes(@Nonnull TestStep testStep) { */ @Nullable protected String getCodeRef(@Nonnull TestStep testStep) { - return ofNullable(getDefinitionMatchField(testStep)).flatMap(match -> { + return ofNullable(getDefinitionMatch(testStep)).map(m -> (StepDefinitionMatch) m).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); @@ -1033,26 +1036,17 @@ 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"); case AfterStep: - name = "After step"; - type = "AFTER_METHOD"; - break; + return Pair.of(ItemType.AFTER_METHOD.name(), "After step"); case BeforeStep: - name = "Before step"; - type = "BEFORE_METHOD"; - break; + return Pair.of(ItemType.BEFORE_METHOD.name(), "Before step"); + 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 38924ca..48240a8 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; @@ -47,9 +48,9 @@ * @author Vitaliy Tsvihun */ 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(); private static final String DUMMY_ROOT_SUITE_NAME = "Root User Story"; 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 d532e39..a2cd696 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,13 +37,12 @@ * created in hooks will be attached to these, and not to the actual failing * steps!) * - * @author Sergey_Gvozdyukevich - * @author Serhii Zharskyi - * @author Vitaliy Tsvihun + * @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(); public StepReporter() { super(); diff --git a/src/main/java/com/epam/reportportal/cucumber/Utils.java b/src/main/java/com/epam/reportportal/cucumber/Utils.java index 32a4889..59eec01 100644 --- a/src/main/java/com/epam/reportportal/cucumber/Utils.java +++ b/src/main/java/com/epam/reportportal/cucumber/Utils.java @@ -17,16 +17,15 @@ import com.epam.reportportal.listeners.ItemStatus; 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 javax.annotation.Nonnull; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.IntStream; import static java.util.Optional.ofNullable; @@ -35,11 +34,6 @@ 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 AssertionError("No instances should exist for the class!"); @@ -88,8 +82,7 @@ public static String buildName(String prefix, String infix, String argument) { return (prefix == null ? EMPTY : prefix) + infix + argument; } - public static Method retrieveMethod(Field definitionMatchField, TestStep testStep) throws IllegalAccessException, NoSuchFieldException { - StepDefinitionMatch stepDefinitionMatch = (StepDefinitionMatch) definitionMatchField.get(testStep); + public static Method retrieveMethod(StepDefinitionMatch stepDefinitionMatch) throws IllegalAccessException, NoSuchFieldException { Field stepDefinitionField = stepDefinitionMatch.getClass().getDeclaredField(STEP_DEFINITION_FIELD_NAME); stepDefinitionField.setAccessible(true); Object javaStepDefinition = stepDefinitionField.get(stepDefinitionMatch); @@ -101,69 +94,11 @@ public static Method retrieveMethod(Field definitionMatchField, TestStep testSte public static final java.util.function.Function, List> ARGUMENTS_TRANSFORM = arguments -> ofNullable( arguments).map(args -> args.stream().map(cucumber.api.Argument::getValue).collect(Collectors.toList())).orElse(null); - public static Field getDefinitionMatchField(TestStep testStep) { - - Class clazz = testStep.getClass(); - + public static Object getDefinitionMatch(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 b0c3253..c5f5b85 100644 --- a/src/test/java/com/epam/reportportal/cucumber/ParameterScenarioReporterTest.java +++ b/src/test/java/com/epam/reportportal/cucumber/ParameterScenarioReporterTest.java @@ -7,6 +7,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; @@ -56,7 +57,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 ada942b..345e1d2 100644 --- a/src/test/java/com/epam/reportportal/cucumber/ParameterStepReporterTest.java +++ b/src/test/java/com/epam/reportportal/cucumber/ParameterStepReporterTest.java @@ -7,6 +7,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; @@ -68,7 +69,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( + private static final String TABLE_PARAM = MarkdownUtils.formatDataTable(Arrays.asList( Arrays.asList("key", "value"), Arrays.asList("myKey", "myValue") ));