diff --git a/CHANGELOG.md b/CHANGELOG.md index 327ca81..9971c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog ## [Unreleased] +### Changed +- Client version updated on [5.4.3](https://github.com/reportportal/client-java/releases/tag/5.4.3), by @HardNorth +- Replace "jsr305" annotations with "jakarta.annotation-api", by @HardNorth +- Switch on use of `Instant` class instead of `Date` to get more timestamp precision, by @HardNorth +### Fixed +- Issue [#43](https://github.com/reportportal/agent-java-karate/issues/43) NullpointerException in case of `null` parameter in Examples, by @HardNorth ## [5.2.2] ### Changed diff --git a/build.gradle b/build.gradle index ba18265..ff117ff 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,7 @@ dependencies { api "com.epam.reportportal:client-java:${client_version}" compileOnly "com.intuit.karate:karate-core:${karate_version}" implementation "org.slf4j:slf4j-api:${slf4j_api_version}" + implementation "org.apache.commons:commons-lang3:3.18.0" testImplementation "com.intuit.karate:karate-core:${karate_version}" testImplementation "com.epam.reportportal:logger-java-logback:${logger_version}" @@ -55,6 +56,7 @@ dependencies { testImplementation "org.mockito:mockito-junit-jupiter:${mockito_version}" testImplementation "org.hamcrest:hamcrest-core:${hamcrest_version}" testImplementation "com.squareup.okhttp3:okhttp:${okhttp_version}" + testImplementation "org.apache.commons:commons-lang3:3.18.0" } test { diff --git a/gradle.properties b/gradle.properties index 09b39ae..45c378a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,16 +1,16 @@ name=agent-java-karate -version=5.2.3-SNAPSHOT +version=5.3.0-SNAPSHOT description=EPAM ReportPortal. Karate test framework [1.3.1, ) adapter gradle_version=8.2 karate_version=1.4.1 junit_version=5.10.1 mockito_version=5.4.0 -test_utils_version=0.0.13 -client_version=5.3.17 +test_utils_version=0.1.0 +client_version=5.4.3 slf4j_api_version=2.0.7 -logger_version=5.2.3 +logger_version=5.4.0 hamcrest_version=2.2 okhttp_version=4.12.0 scripts_url=https://raw.githubusercontent.com/reportportal/gradle-scripts -scripts_branch=develop +scripts_branch=master excludeTests= diff --git a/src/main/java/com/epam/reportportal/karate/ReportPortalHook.java b/src/main/java/com/epam/reportportal/karate/ReportPortalHook.java index c18872f..77e809b 100644 --- a/src/main/java/com/epam/reportportal/karate/ReportPortalHook.java +++ b/src/main/java/com/epam/reportportal/karate/ReportPortalHook.java @@ -36,13 +36,18 @@ import com.intuit.karate.http.HttpRequest; import com.intuit.karate.http.Response; import io.reactivex.Maybe; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; @@ -63,7 +68,7 @@ public class ReportPortalHook implements RuntimeHook { private final Map> backgroundIdMap = new ConcurrentHashMap<>(); private final Map backgroundStatusMap = new ConcurrentHashMap<>(); private final Map> stepIdMap = new ConcurrentHashMap<>(); - private final Map, Date> stepStartTimeMap = new ConcurrentHashMap<>(); + private final Map, Instant> stepStartTimeMap = new ConcurrentHashMap<>(); private final Set> innerFeatures = Collections.newSetFromMap(new ConcurrentHashMap<>()); private volatile Thread shutDownHook; @@ -175,7 +180,7 @@ public boolean beforeFeature(FeatureRuntime fr) { Maybe itemId = launch.get().startTestItem(scenarioId, rq); innerFeatures.add(itemId); if (StringUtils.isNotBlank(rq.getDescription())) { - ReportPortalUtils.sendLog(itemId, rq.getDescription(), LogLevel.INFO, rq.getStartTime()); + ReportPortalUtils.sendLog(itemId, rq.getDescription(), LogLevel.INFO, (Instant) rq.getStartTime()); } return itemId; } @@ -192,7 +197,7 @@ public boolean beforeFeature(FeatureRuntime fr) { */ @Nonnull protected FinishTestItemRQ buildFinishFeatureRq(@Nonnull FeatureRuntime fr) { - return buildFinishTestItemRq(Calendar.getInstance().getTime(), fr.result.isFailed() ? ItemStatus.FAILED : ItemStatus.PASSED); + return buildFinishTestItemRq(Instant.now(), fr.result.isFailed() ? ItemStatus.FAILED : ItemStatus.PASSED); } @Override @@ -298,7 +303,7 @@ public Maybe startBackground(@Nonnull Step step, @Nonnull ScenarioRuntim @Nonnull @SuppressWarnings("unused") protected FinishTestItemRQ buildFinishBackgroundRq(@Nullable StepResult stepResult, @Nonnull ScenarioRuntime sr) { - return buildFinishTestItemRq(Calendar.getInstance().getTime(), backgroundStatusMap.remove(sr.scenario.getUniqueId())); + return buildFinishTestItemRq(Instant.now(), backgroundStatusMap.remove(sr.scenario.getUniqueId())); } /** @@ -335,17 +340,17 @@ public void afterScenario(ScenarioRuntime sr) { * previous step startTime > current step startTime. * * @param stepId step ID. - * @return step new startTime in Date format. + * @return step new startTime in Instant format. */ @Nonnull - private Date getStepStartTime(@Nullable Maybe stepId) { - Date currentStepStartTime = Calendar.getInstance().getTime(); + private Instant getStepStartTime(@Nullable Maybe stepId) { + Instant currentStepStartTime = Instant.now(); if (stepId == null || stepStartTimeMap.isEmpty()) { return currentStepStartTime; } - Date lastStepStartTime = stepStartTimeMap.get(stepId); + Instant lastStepStartTime = stepStartTimeMap.get(stepId); if (lastStepStartTime.compareTo(currentStepStartTime) >= 0) { - currentStepStartTime.setTime(lastStepStartTime.getTime() + 1); + currentStepStartTime = lastStepStartTime.plus(1, ChronoUnit.MICROS); } return currentStepStartTime; } @@ -361,7 +366,7 @@ private Date getStepStartTime(@Nullable Maybe stepId) { protected StartTestItemRQ buildStartStepRq(@Nonnull Step step, @Nonnull ScenarioRuntime sr) { StartTestItemRQ rq = ReportPortalUtils.buildStartStepRq(step, sr.scenario); Maybe stepId = stepIdMap.get(sr.scenario.getUniqueId()); - Date startTime = getStepStartTime(stepId); + Instant startTime = getStepStartTime(stepId); rq.setStartTime(startTime); return rq; } @@ -388,7 +393,7 @@ public boolean beforeStep(Step step, ScenarioRuntime sr) { String scenarioId = sr.scenario.getUniqueId(); Maybe stepId = launch.get().startTestItem(background ? backgroundId : scenarioIdMap.get(scenarioId), stepRq); - stepStartTimeMap.put(stepId, stepRq.getStartTime()); + stepStartTimeMap.put(stepId, (Instant) stepRq.getStartTime()); stepIdMap.put(scenarioId, stepId); ofNullable(stepRq.getParameters()).filter(params -> !params.isEmpty()) .ifPresent(params -> sendLog(stepId, String.format(PARAMETERS_PATTERN, formatParametersAsTable(params)), LogLevel.INFO)); @@ -430,7 +435,7 @@ public void sendStepResults(StepResult stepResult, ScenarioRuntime sr) { @Nonnull @SuppressWarnings("unused") protected FinishTestItemRQ buildFinishStepRq(@Nonnull StepResult stepResult, @Nonnull ScenarioRuntime sr) { - return buildFinishTestItemRq(Calendar.getInstance().getTime(), getStepStatus(stepResult.getResult().getStatus())); + return buildFinishTestItemRq(Instant.now(), getStepStatus(stepResult.getResult().getStatus())); } private void saveBackgroundStatus(@Nonnull StepResult stepResult, @Nonnull ScenarioRuntime sr) { diff --git a/src/main/java/com/epam/reportportal/karate/ReportPortalPublisher.java b/src/main/java/com/epam/reportportal/karate/ReportPortalPublisher.java index f34aa4e..27adacc 100644 --- a/src/main/java/com/epam/reportportal/karate/ReportPortalPublisher.java +++ b/src/main/java/com/epam/reportportal/karate/ReportPortalPublisher.java @@ -29,12 +29,16 @@ import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; import com.intuit.karate.core.*; import io.reactivex.Maybe; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.function.Supplier; import static com.epam.reportportal.karate.ReportPortalUtils.*; @@ -51,7 +55,7 @@ public class ReportPortalPublisher { protected final MemoizingSupplier launch; private final Map> featureIdMap = new HashMap<>(); private final Map> scenarioIdMap = new HashMap<>(); - private final Map, Long> stepStartTimeMap = new HashMap<>(); + private final Map, Instant> stepStartTimeMap = new HashMap<>(); private Maybe backgroundId; private ItemStatus backgroundStatus; private Maybe stepId; @@ -137,7 +141,7 @@ public void startFeature(@Nonnull FeatureResult featureResult) { */ @Nonnull protected FinishTestItemRQ buildFinishFeatureRq(@Nonnull FeatureResult featureResult) { - return buildFinishTestItemRq(Calendar.getInstance().getTime(), featureResult.isFailed() ? ItemStatus.FAILED : ItemStatus.PASSED); + return buildFinishTestItemRq(Instant.now(), featureResult.isFailed() ? ItemStatus.FAILED : ItemStatus.PASSED); } /** @@ -257,7 +261,7 @@ public void startBackground(@Nonnull StepResult stepResult, @Nonnull ScenarioRes @Nonnull @SuppressWarnings("unused") protected FinishTestItemRQ buildFinishBackgroundRq(@Nullable StepResult stepResult, @Nonnull ScenarioResult scenarioResult) { - return buildFinishTestItemRq(Calendar.getInstance().getTime(), backgroundStatus); + return buildFinishTestItemRq(Instant.now(), backgroundStatus); } @@ -282,19 +286,19 @@ public void finishBackground(@Nullable StepResult stepResult, @Nonnull ScenarioR * previous step startTime > current step startTime. * * @param stepId step ID. - * @return step new startTime in Date format. + * @return step new startTime in Instant format. */ - private Date getStepStartTime(@Nonnull Maybe stepId) { - long currentStepStartTime = Calendar.getInstance().getTime().getTime(); + private Instant getStepStartTime(@Nonnull Maybe stepId) { + Instant currentStepStartTime = Instant.now(); if (!stepStartTimeMap.isEmpty()) { - long lastStepStartTime = stepStartTimeMap.get(stepId); + Instant lastStepStartTime = stepStartTimeMap.get(stepId); - if (lastStepStartTime >= currentStepStartTime) { - currentStepStartTime += (lastStepStartTime - currentStepStartTime) + 1; + if (lastStepStartTime.compareTo(currentStepStartTime) >= 0) { + currentStepStartTime = lastStepStartTime.plus(1, ChronoUnit.MICROS); } } - return new Date(currentStepStartTime); + return currentStepStartTime; } /** @@ -307,7 +311,7 @@ private Date getStepStartTime(@Nonnull Maybe stepId) { @Nonnull protected StartTestItemRQ buildStartStepRq(@Nonnull StepResult stepResult, @Nonnull ScenarioResult scenarioResult) { StartTestItemRQ rq = ReportPortalUtils.buildStartStepRq(stepResult.getStep(), scenarioResult.getScenario()); - Date startTime = getStepStartTime(stepId); + Instant startTime = getStepStartTime(stepId); rq.setStartTime(startTime); return rq; } @@ -331,7 +335,7 @@ public void startStep(StepResult stepResult, ScenarioResult scenarioResult) { background && backgroundId != null ? backgroundId : scenarioIdMap.get(scenarioResult.getScenario().getName()), stepRq ); - stepStartTimeMap.put(stepId, stepRq.getStartTime().getTime()); + stepStartTimeMap.put(stepId, (Instant) stepRq.getStartTime()); ofNullable(stepRq.getParameters()).filter(params -> !params.isEmpty()) .ifPresent(params -> sendLog(stepId, String.format(PARAMETERS_PATTERN, formatParametersAsTable(params)), LogLevel.INFO)); ofNullable(step.getTable()).ifPresent(table -> sendLog(stepId, "Table:\n\n" + formatDataTable(table.getRows()), LogLevel.INFO)); @@ -351,7 +355,7 @@ public void startStep(StepResult stepResult, ScenarioResult scenarioResult) { @Nonnull @SuppressWarnings("unused") protected FinishTestItemRQ buildFinishStepRq(@Nonnull StepResult stepResult, @Nonnull ScenarioResult scenarioResult) { - return buildFinishTestItemRq(Calendar.getInstance().getTime(), getStepStatus(stepResult.getResult().getStatus())); + return buildFinishTestItemRq(Instant.now(), getStepStatus(stepResult.getResult().getStatus())); } @SuppressWarnings("unused") diff --git a/src/main/java/com/epam/reportportal/karate/ReportPortalUtils.java b/src/main/java/com/epam/reportportal/karate/ReportPortalUtils.java index 38979d3..618a67f 100644 --- a/src/main/java/com/epam/reportportal/karate/ReportPortalUtils.java +++ b/src/main/java/com/epam/reportportal/karate/ReportPortalUtils.java @@ -37,11 +37,12 @@ import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; import com.intuit.karate.core.*; import io.reactivex.Maybe; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import java.time.Instant; import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -86,7 +87,7 @@ public static String formatExampleKey(@Nonnull final Map example return example.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) - .map(e -> e.getKey() + KEY_VALUE_SEPARATOR + e.getValue().toString()) + .map(e -> e.getKey() + KEY_VALUE_SEPARATOR + ofNullable(e.getValue()).map(Object::toString).orElse(NULL_VALUE)) .collect(Collectors.joining(PARAMETER_ITEMS_DELIMITER, PARAMETER_ITEMS_START, PARAMETER_ITEMS_END)); } @@ -135,7 +136,7 @@ public static void unregisterShutdownHook(@Nonnull Thread hook) { public static StartLaunchRQ buildStartLaunchRq(@Nonnull ListenerParameters parameters) { StartLaunchRQ rq = new StartLaunchRQ(); rq.setName(parameters.getLaunchName()); - rq.setStartTime(Calendar.getInstance().getTime()); + rq.setStartTime(Instant.now()); rq.setMode(parameters.getLaunchRunningMode()); rq.setAttributes(new HashSet<>(parameters.getAttributes())); if (isNotBlank(parameters.getDescription())) { @@ -166,7 +167,7 @@ public static StartLaunchRQ buildStartLaunchRq(@Nonnull ListenerParameters param @SuppressWarnings("unused") public static FinishExecutionRQ buildFinishLaunchRq(@Nonnull ListenerParameters parameters) { FinishExecutionRQ rq = new FinishExecutionRQ(); - rq.setEndTime(Calendar.getInstance().getTime()); + rq.setEndTime(Instant.now()); return rq; } @@ -200,12 +201,12 @@ public static String getCodeRef(@Nonnull Scenario scenario) { * Build default start test item event/request * * @param name item's name - * @param startTime item's start time in Date format + * @param startTime item's start time in Instant format * @param type item's type (e.g. feature, scenario, step, etc.) * @return request to ReportPortal */ @Nonnull - public static StartTestItemRQ buildStartTestItemRq(@Nonnull String name, @Nonnull Date startTime, @Nonnull ItemType type) { + public static StartTestItemRQ buildStartTestItemRq(@Nonnull String name, @Nonnull Instant startTime, @Nonnull ItemType type) { StartTestItemRQ rq = new StartTestItemRQ(); rq.setName(name); rq.setStartTime(startTime); @@ -221,7 +222,7 @@ public static StartTestItemRQ buildStartTestItemRq(@Nonnull String name, @Nonnul * @return request to ReportPortal */ @Nonnull - public static FinishTestItemRQ buildFinishTestItemRq(@Nonnull Date endTime, @Nullable ItemStatus status) { + public static FinishTestItemRQ buildFinishTestItemRq(@Nonnull Instant endTime, @Nullable ItemStatus status) { FinishTestItemRQ rq = new FinishTestItemRQ(); rq.setEndTime(endTime); rq.setStatus(ofNullable(status).map(Enum::name).orElse(null)); @@ -248,7 +249,7 @@ public static Set toAttributes(@Nullable List tags) { @Nonnull public static StartTestItemRQ buildStartFeatureRq(@Nonnull Feature feature) { String featureName = ofNullable(feature.getName()).filter(n -> !n.isBlank()).orElseGet(() -> getCodeRef(feature)); - StartTestItemRQ rq = buildStartTestItemRq(featureName, Calendar.getInstance().getTime(), ItemType.STORY); + StartTestItemRQ rq = buildStartTestItemRq(featureName, Instant.now(), ItemType.STORY); rq.setAttributes(toAttributes(feature.getTags())); String featurePath = feature.getResource().getUri().toString(); String description = feature.getDescription(); @@ -310,7 +311,7 @@ public static TestCaseIdEntry getTestCaseId(@Nonnull Scenario scenario) { @Nonnull public static StartTestItemRQ buildStartScenarioRq(@Nonnull ScenarioResult result) { Scenario scenario = result.getScenario(); - StartTestItemRQ rq = buildStartTestItemRq(scenario.getName(), Calendar.getInstance().getTime(), ItemType.STEP); + StartTestItemRQ rq = buildStartTestItemRq(scenario.getName(), Instant.now(), ItemType.STEP); rq.setCodeRef(getCodeRef(scenario)); rq.setTestCaseId(ofNullable(getTestCaseId(scenario)).map(TestCaseIdEntry::getId).orElse(null)); rq.setAttributes(toAttributes(scenario.getTags())); @@ -329,7 +330,7 @@ public static StartTestItemRQ buildStartScenarioRq(@Nonnull ScenarioResult resul public static FinishTestItemRQ buildFinishScenarioRq(@Nonnull ScenarioResult result) { Scenario scenario = result.getScenario(); FinishTestItemRQ rq = buildFinishTestItemRq( - Calendar.getInstance().getTime(), + Instant.now(), result.getFailureMessageForDisplay() == null ? ItemStatus.PASSED : ItemStatus.FAILED ); rq.setDescription(buildDescription(scenario, result.getErrorMessage(), getParameters(scenario))); @@ -371,7 +372,7 @@ private static void appendWithDelimiter(StringBuilder builder, String text) { @Nonnull @SuppressWarnings("unused") public static StartTestItemRQ buildStartBackgroundRq(@Nonnull Step step, @Nonnull Scenario scenario) { - StartTestItemRQ rq = buildStartTestItemRq(Background.KEYWORD, Calendar.getInstance().getTime(), ItemType.STEP); + StartTestItemRQ rq = buildStartTestItemRq(Background.KEYWORD, Instant.now(), ItemType.STEP); rq.setHasStats(false); return rq; } @@ -386,7 +387,7 @@ public static StartTestItemRQ buildStartBackgroundRq(@Nonnull Step step, @Nonnul @Nonnull public static StartTestItemRQ buildStartStepRq(@Nonnull Step step, @Nonnull Scenario scenario) { String stepName = step.getPrefix() + " " + step.getText(); - StartTestItemRQ rq = buildStartTestItemRq(stepName, Calendar.getInstance().getTime(), ItemType.STEP); + StartTestItemRQ rq = buildStartTestItemRq(stepName, Instant.now(), ItemType.STEP); rq.setHasStats(false); if (step.isOutline()) { List parameters = scenario.getExampleData() @@ -440,7 +441,7 @@ public static ItemStatus getStepStatus(String status) { * @param level log level * @param logTime log time */ - public static void sendLog(Maybe itemId, String message, LogLevel level, Date logTime) { + public static void sendLog(Maybe itemId, String message, LogLevel level, Instant logTime) { ReportPortal.emitLog( itemId, id -> { SaveLogRQ rq = new SaveLogRQ(); @@ -461,7 +462,7 @@ public static void sendLog(Maybe itemId, String message, LogLevel level, * @param level log level */ public static void sendLog(Maybe itemId, String message, LogLevel level) { - sendLog(itemId, message, level, Calendar.getInstance().getTime()); + sendLog(itemId, message, level, Instant.now()); } /** diff --git a/src/main/java/com/epam/reportportal/karate/utils/BlockingConcurrentHashMap.java b/src/main/java/com/epam/reportportal/karate/utils/BlockingConcurrentHashMap.java index f699e6d..20a31e9 100644 --- a/src/main/java/com/epam/reportportal/karate/utils/BlockingConcurrentHashMap.java +++ b/src/main/java/com/epam/reportportal/karate/utils/BlockingConcurrentHashMap.java @@ -16,11 +16,11 @@ package com.epam.reportportal.karate.utils; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.util.Map; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; diff --git a/src/test/java/com/epam/reportportal/karate/call/CallTheSameFeatureWithParametersHookTest.java b/src/test/java/com/epam/reportportal/karate/call/CallTheSameFeatureWithParametersHookTest.java index b39e48c..220bce7 100644 --- a/src/test/java/com/epam/reportportal/karate/call/CallTheSameFeatureWithParametersHookTest.java +++ b/src/test/java/com/epam/reportportal/karate/call/CallTheSameFeatureWithParametersHookTest.java @@ -37,7 +37,7 @@ import static com.epam.reportportal.karate.utils.TestUtils.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.equalTo; import static org.mockito.Mockito.*; public class CallTheSameFeatureWithParametersHookTest { @@ -45,21 +45,27 @@ public class CallTheSameFeatureWithParametersHookTest { private final String featureId = CommonUtils.namedId("feature_"); private final String scenarioId = CommonUtils.namedId("scenario_"); private final String innerFeatureId = CommonUtils.namedId("feature_step_"); - private final List stepIds = Arrays.asList(CommonUtils.namedId("step_"), CommonUtils.namedId("step_"), - CommonUtils.namedId("step_"), innerFeatureId); + private final List stepIds = Arrays.asList( + CommonUtils.namedId("step_"), + CommonUtils.namedId("step_"), + CommonUtils.namedId("step_"), + innerFeatureId + ); private final String innerScenarioId = CommonUtils.namedId("scenario_step_"); private final List innerStepIds = Stream.generate(() -> CommonUtils.namedId("inner_step_")) .limit(4) .collect(Collectors.toList()); - private final List>>>> features = Stream.of(Pair.of(featureId, + private final List>>>> features = Stream.of(Pair.of( + featureId, (Collection>>) Collections.singletonList(Pair.of(scenarioId, stepIds)) )) .collect(Collectors.toList()); private final List> nestedSteps = Stream.concat( - Stream.of(Pair.of(innerFeatureId, innerScenarioId)), - innerStepIds.stream().map(id -> Pair.of(innerScenarioId, id)) - ).collect(Collectors.toList()); + Stream.of(Pair.of(innerFeatureId, innerScenarioId)), + innerStepIds.stream().map(id -> Pair.of(innerScenarioId, id)) + ) + .collect(Collectors.toList()); private final ReportPortalClient client = mock(ReportPortalClient.class); private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); diff --git a/src/test/java/com/epam/reportportal/karate/call/CallWithParametersHookTest.java b/src/test/java/com/epam/reportportal/karate/call/CallWithParametersHookTest.java index b1f06e8..44975a6 100644 --- a/src/test/java/com/epam/reportportal/karate/call/CallWithParametersHookTest.java +++ b/src/test/java/com/epam/reportportal/karate/call/CallWithParametersHookTest.java @@ -37,9 +37,9 @@ import static com.epam.reportportal.karate.utils.TestUtils.*; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.*; public class CallWithParametersHookTest { @@ -58,14 +58,16 @@ public class CallWithParametersHookTest { .limit(3) .collect(Collectors.toList()); - private final List>>>> features = Stream.of(Pair.of(featureId, + private final List>>>> features = Stream.of(Pair.of( + featureId, (Collection>>) Collections.singletonList(Pair.of(scenarioId, stepIds)) )) .collect(Collectors.toList()); private final List> nestedSteps = Stream.concat( - Stream.of(Pair.of(innerFeatureId, innerScenarioId)), - innerStepIds.stream().map(id -> Pair.of(innerScenarioId, id)) - ).collect(Collectors.toList()); + Stream.of(Pair.of(innerFeatureId, innerScenarioId)), + innerStepIds.stream().map(id -> Pair.of(innerScenarioId, id)) + ) + .collect(Collectors.toList()); private final ReportPortalClient client = mock(ReportPortalClient.class); private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); diff --git a/src/test/java/com/epam/reportportal/karate/description/NoDescriptionTest.java b/src/test/java/com/epam/reportportal/karate/description/NoDescriptionTest.java index b35ccd8..6effb32 100644 --- a/src/test/java/com/epam/reportportal/karate/description/NoDescriptionTest.java +++ b/src/test/java/com/epam/reportportal/karate/description/NoDescriptionTest.java @@ -33,8 +33,8 @@ import static com.epam.reportportal.karate.utils.TestUtils.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.endsWith; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.*; diff --git a/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithDescriptionAndExamplesTest.java b/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithDescriptionAndExamplesTest.java index a586ef7..189c7af 100644 --- a/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithDescriptionAndExamplesTest.java +++ b/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithDescriptionAndExamplesTest.java @@ -48,84 +48,87 @@ public class ScenarioDescriptionErrorLogWithDescriptionAndExamplesTest { - public static final String MARKDOWN_DELIMITER_PATTERN_THREE_ARGS = "%s\n\n---\n\n%s\n\n---\n\n%s"; - public static final String ERROR = "did not evaluate to 'true': mathResult == 5\nclasspath:feature/simple_failed_description_examples.feature:8"; - public static final String ERROR_MESSAGE = "Then assert mathResult == 5\n" + ERROR; - public static final String DESCRIPTION_ERROR_LOG = "Error:\n" + ERROR; - public static final String DESCRIPTION = "This is my Scenario description."; - private static final String EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN = - "Parameters:\n\n" + MarkdownUtils.TABLE_INDENT + "| vara | varb | result |\n" + MarkdownUtils.TABLE_INDENT - + "|------|------|--------|\n" + MarkdownUtils.TABLE_INDENT; - public static final String FIRST_EXAMPLE_DESCRIPTION = EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN + "|  2   |  2   |   4    |"; - public static final String SECOND_EXAMPLE_DESCRIPTION = EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN + "|  1   |  2   |   5    |"; - - public static final String FIRST_EXAMPLE_DESCRIPTION_WITHOUT_ERROR_LOG = String.format( - MARKDOWN_DELIMITER_PATTERN, - FIRST_EXAMPLE_DESCRIPTION, - DESCRIPTION - ); - public static final String SECOND_EXAMPLE_DESCRIPTION_WITH_ERROR_LOG = String.format( - MARKDOWN_DELIMITER_PATTERN_THREE_ARGS, - SECOND_EXAMPLE_DESCRIPTION, - DESCRIPTION, - DESCRIPTION_ERROR_LOG - ); - - private static final String TEST_FEATURE = "classpath:feature/simple_failed_description_examples.feature"; - private final String featureId = CommonUtils.namedId("feature_"); - private final List exampleIds = Stream.generate(() -> CommonUtils.namedId("example_")).limit(2).collect(Collectors.toList()); - private final List>> stepIds = exampleIds.stream() - .map(e -> Pair.of(e, Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList()))) - .collect(Collectors.toList()); - - private final ReportPortalClient client = mock(ReportPortalClient.class); - private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); - - @BeforeEach - public void setupMock() { - mockLaunch(client, null, featureId, stepIds); - mockBatchLogging(client); - } - - @ParameterizedTest - @ValueSource(booleans = {true, false}) - public void test_error_log_and_examples_in_description(boolean report) { - Results results; - - if (report) { - results = TestUtils.runAsReport(rp, TEST_FEATURE); - } else { - results = TestUtils.runAsHook(rp, TEST_FEATURE); - } - - assertThat(results.getFailCount(), equalTo(1)); - - @SuppressWarnings("unchecked") - ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); - verify(client, atLeastOnce()).log(logCaptor.capture()); - List logs = logCaptor.getAllValues() - .stream() - .flatMap(rq -> extractJsonParts(rq).stream()) - .filter(rq -> LogLevel.ERROR.name().equals(rq.getLevel())) - .collect(Collectors.toList()); - - assertThat(logs, hasSize(greaterThan(0))); - SaveLogRQ log = logs.get(logs.size() - 1); - assertThat(log.getMessage(), equalTo(ERROR_MESSAGE)); - - ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); - verify(client).finishTestItem(same(exampleIds.get(0)), scenarioCaptor.capture()); - verify(client).finishTestItem(same(exampleIds.get(1)), scenarioCaptor.capture()); - - List> stepCaptors = new ArrayList<>(Collections.nCopies(stepIds.size(), ArgumentCaptor.forClass(FinishTestItemRQ.class))); - stepIds.forEach(pair -> pair.getValue().forEach(id -> verify(client).finishTestItem(same(id), stepCaptors.get(0).capture()))); - - FinishTestItemRQ firstScenarioRq = scenarioCaptor.getAllValues().get(0); - assertThat(firstScenarioRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.PASSED.name()))); - assertThat(firstScenarioRq.getDescription(), allOf(notNullValue(), equalTo(FIRST_EXAMPLE_DESCRIPTION_WITHOUT_ERROR_LOG))); - - FinishTestItemRQ secondScenarioRq = scenarioCaptor.getAllValues().get(1); - assertThat(secondScenarioRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.FAILED.name()))); - assertThat(secondScenarioRq.getDescription(), allOf(notNullValue(), equalTo(SECOND_EXAMPLE_DESCRIPTION_WITH_ERROR_LOG))); - } + public static final String MARKDOWN_DELIMITER_PATTERN_THREE_ARGS = "%s\n\n---\n\n%s\n\n---\n\n%s"; + public static final String ERROR = "did not evaluate to 'true': mathResult == 5\nclasspath:feature/simple_failed_description_examples.feature:8"; + public static final String ERROR_MESSAGE = "Then assert mathResult == 5\n" + ERROR; + public static final String DESCRIPTION_ERROR_LOG = "Error:\n" + ERROR; + public static final String DESCRIPTION = "This is my Scenario description."; + private static final String EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN = + "Parameters:\n\n" + MarkdownUtils.TABLE_INDENT + "| vara | varb | result |\n" + MarkdownUtils.TABLE_INDENT + + "|------|------|--------|\n" + MarkdownUtils.TABLE_INDENT; + public static final String FIRST_EXAMPLE_DESCRIPTION = EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN + "|  2   |  2   |   4    |"; + public static final String SECOND_EXAMPLE_DESCRIPTION = EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN + "|  1   |  2   |   5    |"; + + public static final String FIRST_EXAMPLE_DESCRIPTION_WITHOUT_ERROR_LOG = String.format( + MARKDOWN_DELIMITER_PATTERN, + FIRST_EXAMPLE_DESCRIPTION, + DESCRIPTION + ); + public static final String SECOND_EXAMPLE_DESCRIPTION_WITH_ERROR_LOG = String.format( + MARKDOWN_DELIMITER_PATTERN_THREE_ARGS, + SECOND_EXAMPLE_DESCRIPTION, + DESCRIPTION, + DESCRIPTION_ERROR_LOG + ); + + private static final String TEST_FEATURE = "classpath:feature/simple_failed_description_examples.feature"; + private final String featureId = CommonUtils.namedId("feature_"); + private final List exampleIds = Stream.generate(() -> CommonUtils.namedId("example_")).limit(2).collect(Collectors.toList()); + private final List>> stepIds = exampleIds.stream() + .map(e -> Pair.of(e, Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList()))) + .collect(Collectors.toList()); + + private final ReportPortalClient client = mock(ReportPortalClient.class); + private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); + + @BeforeEach + public void setupMock() { + mockLaunch(client, null, featureId, stepIds); + mockBatchLogging(client); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + public void test_error_log_and_examples_in_description(boolean report) { + Results results; + + if (report) { + results = TestUtils.runAsReport(rp, TEST_FEATURE); + } else { + results = TestUtils.runAsHook(rp, TEST_FEATURE); + } + + assertThat(results.getFailCount(), equalTo(1)); + + @SuppressWarnings("unchecked") + ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); + verify(client, atLeastOnce()).log(logCaptor.capture()); + List logs = logCaptor.getAllValues() + .stream() + .flatMap(rq -> extractJsonParts(rq).stream()) + .filter(rq -> LogLevel.ERROR.name().equals(rq.getLevel())) + .collect(Collectors.toList()); + + assertThat(logs, hasSize(greaterThan(0))); + SaveLogRQ log = logs.get(logs.size() - 1); + assertThat(log.getMessage(), equalTo(ERROR_MESSAGE)); + + ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(client).finishTestItem(same(exampleIds.get(0)), scenarioCaptor.capture()); + verify(client).finishTestItem(same(exampleIds.get(1)), scenarioCaptor.capture()); + + List> stepCaptors = new ArrayList<>(Collections.nCopies( + stepIds.size(), + ArgumentCaptor.forClass(FinishTestItemRQ.class) + )); + stepIds.forEach(pair -> pair.getValue().forEach(id -> verify(client).finishTestItem(same(id), stepCaptors.get(0).capture()))); + + FinishTestItemRQ firstScenarioRq = scenarioCaptor.getAllValues().get(0); + assertThat(firstScenarioRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.PASSED.name()))); + assertThat(firstScenarioRq.getDescription(), allOf(notNullValue(), equalTo(FIRST_EXAMPLE_DESCRIPTION_WITHOUT_ERROR_LOG))); + + FinishTestItemRQ secondScenarioRq = scenarioCaptor.getAllValues().get(1); + assertThat(secondScenarioRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.FAILED.name()))); + assertThat(secondScenarioRq.getDescription(), allOf(notNullValue(), equalTo(SECOND_EXAMPLE_DESCRIPTION_WITH_ERROR_LOG))); + } } diff --git a/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithDescriptionTest.java b/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithDescriptionTest.java index 454066c..3b39320 100644 --- a/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithDescriptionTest.java +++ b/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithDescriptionTest.java @@ -43,62 +43,61 @@ public class ScenarioDescriptionErrorLogWithDescriptionTest { - public static final String ERROR = "did not evaluate to 'true': actualFour != four\nclasspath:feature/simple_failed_description.feature:9"; - public static final String ERROR_MESSAGE = "Then assert actualFour != four\n" + ERROR; - public static final String DESCRIPTION_ERROR_LOG = "Error:\n" + ERROR; - public static final String DESCRIPTION = "This is my Scenario description."; - public static final String DESCRIPTION_ERROR_LOG_WITH_DESCRIPTION = String.format( - MARKDOWN_DELIMITER_PATTERN, - DESCRIPTION, - DESCRIPTION_ERROR_LOG - ); - private static final String TEST_FEATURE = "classpath:feature/simple_failed_description.feature"; - private final String launchUuid = CommonUtils.namedId("launch_"); - private final String featureId = CommonUtils.namedId("feature_"); - private final String scenarioId = CommonUtils.namedId("scenario_"); - private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); - private final ReportPortalClient client = mock(ReportPortalClient.class); - private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); + public static final String ERROR = "did not evaluate to 'true': actualFour != four\nclasspath:feature/simple_failed_description.feature:9"; + public static final String ERROR_MESSAGE = "Then assert actualFour != four\n" + ERROR; + public static final String DESCRIPTION_ERROR_LOG = "Error:\n" + ERROR; + public static final String DESCRIPTION = "This is my Scenario description."; + public static final String DESCRIPTION_ERROR_LOG_WITH_DESCRIPTION = String.format( + MARKDOWN_DELIMITER_PATTERN, + DESCRIPTION, + DESCRIPTION_ERROR_LOG + ); + private static final String TEST_FEATURE = "classpath:feature/simple_failed_description.feature"; + private final String launchUuid = CommonUtils.namedId("launch_"); + private final String featureId = CommonUtils.namedId("feature_"); + private final String scenarioId = CommonUtils.namedId("scenario_"); + private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()); + private final ReportPortalClient client = mock(ReportPortalClient.class); + private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); - @BeforeEach - public void setupMock() { - mockLaunch(client, launchUuid, featureId, scenarioId, stepIds); - mockBatchLogging(client); - } + @BeforeEach + public void setupMock() { + mockLaunch(client, launchUuid, featureId, scenarioId, stepIds); + mockBatchLogging(client); + } - @ParameterizedTest - @ValueSource(booleans = {true, false}) - public void test_error_log_and_description_in_description(boolean report) { - Results results; - if (report) { - results = TestUtils.runAsReport(rp, TEST_FEATURE); - } else { - results = TestUtils.runAsHook(rp, TEST_FEATURE); - } - assertThat(results.getFailCount(), equalTo(1)); + @ParameterizedTest + @ValueSource(booleans = { true, false }) + public void test_error_log_and_description_in_description(boolean report) { + Results results; + if (report) { + results = TestUtils.runAsReport(rp, TEST_FEATURE); + } else { + results = TestUtils.runAsHook(rp, TEST_FEATURE); + } + assertThat(results.getFailCount(), equalTo(1)); - @SuppressWarnings("unchecked") - ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); - verify(client, atLeastOnce()).log(logCaptor.capture()); - List logs = logCaptor.getAllValues() - .stream() - .flatMap(rq -> extractJsonParts(rq).stream()) - .filter(rq -> LogLevel.ERROR.name().equals(rq.getLevel())) - .collect(Collectors.toList()); + @SuppressWarnings("unchecked") + ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); + verify(client, atLeastOnce()).log(logCaptor.capture()); + List logs = logCaptor.getAllValues() + .stream() + .flatMap(rq -> extractJsonParts(rq).stream()) + .filter(rq -> LogLevel.ERROR.name().equals(rq.getLevel())) + .collect(Collectors.toList()); - assertThat(logs, hasSize(greaterThan(0))); - SaveLogRQ log = logs.get(logs.size() - 1); - assertThat(log.getItemUuid(), oneOf(stepIds.toArray(new String[0]))); - assertThat(log.getLaunchUuid(), equalTo(launchUuid)); - assertThat(log.getMessage(), equalTo(ERROR_MESSAGE) - ); + assertThat(logs, hasSize(greaterThan(0))); + SaveLogRQ log = logs.get(logs.size() - 1); + assertThat(log.getItemUuid(), oneOf(stepIds.toArray(new String[0]))); + assertThat(log.getLaunchUuid(), equalTo(launchUuid)); + assertThat(log.getMessage(), equalTo(ERROR_MESSAGE)); - ArgumentCaptor scenarioCaptorFinish = ArgumentCaptor.forClass(FinishTestItemRQ.class); - verify(client, times(1)).finishTestItem(same(scenarioId), scenarioCaptorFinish.capture()); + ArgumentCaptor scenarioCaptorFinish = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(client, times(1)).finishTestItem(same(scenarioId), scenarioCaptorFinish.capture()); - List scenarios = scenarioCaptorFinish.getAllValues(); - FinishTestItemRQ scenario = scenarios.get(0); + List scenarios = scenarioCaptorFinish.getAllValues(); + FinishTestItemRQ scenario = scenarios.get(0); - assertThat(scenario.getDescription(), allOf(notNullValue(), equalTo(DESCRIPTION_ERROR_LOG_WITH_DESCRIPTION))); - } + assertThat(scenario.getDescription(), allOf(notNullValue(), equalTo(DESCRIPTION_ERROR_LOG_WITH_DESCRIPTION))); + } } diff --git a/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithExamplesTest.java b/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithExamplesTest.java index 81ca439..8cd7503 100644 --- a/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithExamplesTest.java +++ b/src/test/java/com/epam/reportportal/karate/description/ScenarioDescriptionErrorLogWithExamplesTest.java @@ -48,76 +48,79 @@ public class ScenarioDescriptionErrorLogWithExamplesTest { - public static final String ERROR = "did not evaluate to 'true': mathResult == 5\nclasspath:feature/simple_failed_examples.feature:5"; - public static final String ERROR_MESSAGE = "Then assert mathResult == 5\n" + ERROR; - public static final String DESCRIPTION_ERROR_LOG = "Error:\n" + ERROR; - private static final String EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN = - "Parameters:\n\n" + MarkdownUtils.TABLE_INDENT + "| vara | varb | result |\n" + MarkdownUtils.TABLE_INDENT - + "|------|------|--------|\n" + MarkdownUtils.TABLE_INDENT; - public static final String FIRST_EXAMPLE_DESCRIPTION = EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN + "|  2   |  2   |   4    |"; - public static final String SECOND_EXAMPLE_DESCRIPTION = EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN + "|  1   |  2   |   5    |"; - - public static final String SECOND_EXAMPLE_DESCRIPTION_WITH_ERROR_LOG = String.format( - MARKDOWN_DELIMITER_PATTERN, - SECOND_EXAMPLE_DESCRIPTION, - DESCRIPTION_ERROR_LOG - ); - - private static final String TEST_FEATURE = "classpath:feature/simple_failed_examples.feature"; - private final String featureId = CommonUtils.namedId("feature_"); - private final List exampleIds = Stream.generate(() -> CommonUtils.namedId("example_")).limit(2).collect(Collectors.toList()); - private final List>> stepIds = exampleIds.stream() - .map(e -> Pair.of(e, Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList()))) - .collect(Collectors.toList()); - - private final ReportPortalClient client = mock(ReportPortalClient.class); - private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); - - @BeforeEach - public void setupMock() { - mockLaunch(client, null, featureId, stepIds); - mockBatchLogging(client); - } - - @ParameterizedTest - @ValueSource(booleans = {true, false}) - public void test_error_log_and_examples_in_description(boolean report) { - Results results; - - if (report) { - results = TestUtils.runAsReport(rp, TEST_FEATURE); - } else { - results = TestUtils.runAsHook(rp, TEST_FEATURE); - } - - assertThat(results.getFailCount(), equalTo(1)); - - @SuppressWarnings("unchecked") - ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); - verify(client, atLeastOnce()).log(logCaptor.capture()); - List logs = logCaptor.getAllValues() - .stream() - .flatMap(rq -> extractJsonParts(rq).stream()) - .filter(rq -> LogLevel.ERROR.name().equals(rq.getLevel())) - .collect(Collectors.toList()); - - assertThat(logs, hasSize(greaterThan(0))); - SaveLogRQ log = logs.get(logs.size() - 1); - assertThat(log.getMessage(), equalTo(ERROR_MESSAGE)); - - ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); - verify(client).finishTestItem(same(exampleIds.get(0)), scenarioCaptor.capture()); - verify(client).finishTestItem(same(exampleIds.get(1)), scenarioCaptor.capture()); - - List> stepCaptors = new ArrayList<>(Collections.nCopies(stepIds.size(), ArgumentCaptor.forClass(FinishTestItemRQ.class))); - stepIds.forEach(pair -> pair.getValue().forEach(id -> verify(client).finishTestItem(same(id), stepCaptors.get(0).capture()))); - - FinishTestItemRQ firstScenarioRq = scenarioCaptor.getAllValues().get(0); - assertThat(firstScenarioRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.PASSED.name()))); - assertThat(firstScenarioRq.getDescription(), allOf(notNullValue(), equalTo(FIRST_EXAMPLE_DESCRIPTION))); - - FinishTestItemRQ secondScenarioRq = scenarioCaptor.getAllValues().get(1); - assertThat(secondScenarioRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.FAILED.name()))); - assertThat(secondScenarioRq.getDescription(), allOf(notNullValue(), equalTo(SECOND_EXAMPLE_DESCRIPTION_WITH_ERROR_LOG))); - } + public static final String ERROR = "did not evaluate to 'true': mathResult == 5\nclasspath:feature/simple_failed_examples.feature:5"; + public static final String ERROR_MESSAGE = "Then assert mathResult == 5\n" + ERROR; + public static final String DESCRIPTION_ERROR_LOG = "Error:\n" + ERROR; + private static final String EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN = + "Parameters:\n\n" + MarkdownUtils.TABLE_INDENT + "| vara | varb | result |\n" + MarkdownUtils.TABLE_INDENT + + "|------|------|--------|\n" + MarkdownUtils.TABLE_INDENT; + public static final String FIRST_EXAMPLE_DESCRIPTION = EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN + "|  2   |  2   |   4    |"; + public static final String SECOND_EXAMPLE_DESCRIPTION = EXAMPLE_PARAMETERS_DESCRIPTION_PATTERN + "|  1   |  2   |   5    |"; + + public static final String SECOND_EXAMPLE_DESCRIPTION_WITH_ERROR_LOG = String.format( + MARKDOWN_DELIMITER_PATTERN, + SECOND_EXAMPLE_DESCRIPTION, + DESCRIPTION_ERROR_LOG + ); + + private static final String TEST_FEATURE = "classpath:feature/simple_failed_examples.feature"; + private final String featureId = CommonUtils.namedId("feature_"); + private final List exampleIds = Stream.generate(() -> CommonUtils.namedId("example_")).limit(2).collect(Collectors.toList()); + private final List>> stepIds = exampleIds.stream() + .map(e -> Pair.of(e, Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList()))) + .collect(Collectors.toList()); + + private final ReportPortalClient client = mock(ReportPortalClient.class); + private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); + + @BeforeEach + public void setupMock() { + mockLaunch(client, null, featureId, stepIds); + mockBatchLogging(client); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + public void test_error_log_and_examples_in_description(boolean report) { + Results results; + + if (report) { + results = TestUtils.runAsReport(rp, TEST_FEATURE); + } else { + results = TestUtils.runAsHook(rp, TEST_FEATURE); + } + + assertThat(results.getFailCount(), equalTo(1)); + + @SuppressWarnings("unchecked") + ArgumentCaptor> logCaptor = ArgumentCaptor.forClass(List.class); + verify(client, atLeastOnce()).log(logCaptor.capture()); + List logs = logCaptor.getAllValues() + .stream() + .flatMap(rq -> extractJsonParts(rq).stream()) + .filter(rq -> LogLevel.ERROR.name().equals(rq.getLevel())) + .collect(Collectors.toList()); + + assertThat(logs, hasSize(greaterThan(0))); + SaveLogRQ log = logs.get(logs.size() - 1); + assertThat(log.getMessage(), equalTo(ERROR_MESSAGE)); + + ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(client).finishTestItem(same(exampleIds.get(0)), scenarioCaptor.capture()); + verify(client).finishTestItem(same(exampleIds.get(1)), scenarioCaptor.capture()); + + List> stepCaptors = new ArrayList<>(Collections.nCopies( + stepIds.size(), + ArgumentCaptor.forClass(FinishTestItemRQ.class) + )); + stepIds.forEach(pair -> pair.getValue().forEach(id -> verify(client).finishTestItem(same(id), stepCaptors.get(0).capture()))); + + FinishTestItemRQ firstScenarioRq = scenarioCaptor.getAllValues().get(0); + assertThat(firstScenarioRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.PASSED.name()))); + assertThat(firstScenarioRq.getDescription(), allOf(notNullValue(), equalTo(FIRST_EXAMPLE_DESCRIPTION))); + + FinishTestItemRQ secondScenarioRq = scenarioCaptor.getAllValues().get(1); + assertThat(secondScenarioRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.FAILED.name()))); + assertThat(secondScenarioRq.getDescription(), allOf(notNullValue(), equalTo(SECOND_EXAMPLE_DESCRIPTION_WITH_ERROR_LOG))); + } } diff --git a/src/test/java/com/epam/reportportal/karate/description/SimpleDescriptionTest.java b/src/test/java/com/epam/reportportal/karate/description/SimpleDescriptionTest.java index 2e621e7..f328579 100644 --- a/src/test/java/com/epam/reportportal/karate/description/SimpleDescriptionTest.java +++ b/src/test/java/com/epam/reportportal/karate/description/SimpleDescriptionTest.java @@ -35,8 +35,8 @@ import static com.epam.reportportal.karate.utils.TestUtils.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.endsWith; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.*; diff --git a/src/test/java/com/epam/reportportal/karate/launch/LaunchRequiredFieldsTest.java b/src/test/java/com/epam/reportportal/karate/launch/LaunchRequiredFieldsTest.java index 52be11a..3e37dcb 100644 --- a/src/test/java/com/epam/reportportal/karate/launch/LaunchRequiredFieldsTest.java +++ b/src/test/java/com/epam/reportportal/karate/launch/LaunchRequiredFieldsTest.java @@ -27,6 +27,7 @@ import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; +import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -70,7 +71,10 @@ public void verify_start_launch_request_contains_required_fields(boolean report) StartLaunchRQ launchStart = startCaptor.getValue(); assertThat(launchStart.getName(), startsWith("My-test-launch")); assertThat(launchStart.getStartTime(), notNullValue()); - assertThat(System.currentTimeMillis() - launchStart.getStartTime().getTime(), not(greaterThan(TimeUnit.SECONDS.toMillis(10)))); + assertThat( + System.currentTimeMillis() - ((Date) launchStart.getStartTime()).getTime(), + not(greaterThan(TimeUnit.SECONDS.toMillis(10))) + ); } } diff --git a/src/test/java/com/epam/reportportal/karate/logging/HttpRequestLoggingTest.java b/src/test/java/com/epam/reportportal/karate/logging/HttpRequestLoggingTest.java index fa90a4a..7079575 100644 --- a/src/test/java/com/epam/reportportal/karate/logging/HttpRequestLoggingTest.java +++ b/src/test/java/com/epam/reportportal/karate/logging/HttpRequestLoggingTest.java @@ -76,10 +76,10 @@ public void test_http_request_logging(boolean report) { assertThat(logs, hasSize(greaterThanOrEqualTo(2))); List messages = logs.stream().map(SaveLogRQ::getMessage).collect(Collectors.toList()); - assertThat(messages, - hasItems(equalTo( - "Docstring:\n\n```\n{\n" + " username: 'user',\n" + " password: 'password',\n" + " grant_type: 'password'\n" - + "}\n```"), + assertThat( + messages, hasItems( + equalTo("Docstring:\n\n```\n{\n" + " username: 'user',\n" + " password: 'password',\n" + + " grant_type: 'password'\n" + "}\n```"), containsString("{\"username\":\"user\",\"password\":\"password\",\"grant_type\":\"password\"}") ) ); diff --git a/src/test/java/com/epam/reportportal/karate/logging/SimpleFailureLoggingTest.java b/src/test/java/com/epam/reportportal/karate/logging/SimpleFailureLoggingTest.java index 466d1df..7699d95 100644 --- a/src/test/java/com/epam/reportportal/karate/logging/SimpleFailureLoggingTest.java +++ b/src/test/java/com/epam/reportportal/karate/logging/SimpleFailureLoggingTest.java @@ -78,7 +78,8 @@ public void test_simple_one_step_failed_error_log(boolean report) { SaveLogRQ log = logs.get(logs.size() - 1); assertThat(log.getItemUuid(), oneOf(stepIds.toArray(new String[0]))); assertThat(log.getLaunchUuid(), equalTo(launchUuid)); - assertThat(log.getMessage(), + assertThat( + log.getMessage(), equalTo("Then assert actualFour != four\n" + "did not evaluate to 'true': actualFour != four\n" + "classpath:feature/simple_failed.feature:6") ); diff --git a/src/test/java/com/epam/reportportal/karate/parameters/ExamplesStepParametersTest.java b/src/test/java/com/epam/reportportal/karate/parameters/ExamplesStepParametersTest.java index 929b136..030ee07 100644 --- a/src/test/java/com/epam/reportportal/karate/parameters/ExamplesStepParametersTest.java +++ b/src/test/java/com/epam/reportportal/karate/parameters/ExamplesStepParametersTest.java @@ -42,8 +42,8 @@ import static com.epam.reportportal.karate.utils.TestUtils.*; import static java.util.stream.Stream.ofNullable; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.startsWith; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.*; @@ -115,7 +115,8 @@ public void test_examples_parameters_for_steps(boolean report) { List stepIdList = stepIds.stream().flatMap(e -> e.getValue().stream()).collect(Collectors.toList()); assertThat(logs.keySet(), hasSize(stepIdList.size())); stepIdList.forEach(id -> assertThat(logs, hasKey(id))); - assertThat(logs.values().stream().map(SaveLogRQ::getMessage).collect(Collectors.toList()), + assertThat( + logs.values().stream().map(SaveLogRQ::getMessage).collect(Collectors.toList()), everyItem(startsWith("Parameters:\n\n")) ); } diff --git a/src/test/java/com/epam/reportportal/karate/parameters/NullValueExamplesTest.java b/src/test/java/com/epam/reportportal/karate/parameters/NullValueExamplesTest.java new file mode 100644 index 0000000..c535441 --- /dev/null +++ b/src/test/java/com/epam/reportportal/karate/parameters/NullValueExamplesTest.java @@ -0,0 +1,88 @@ +/* + * Copyright 2024 EPAM Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.epam.reportportal.karate.parameters; + +import com.epam.reportportal.karate.utils.TestUtils; +import com.epam.reportportal.service.ReportPortal; +import com.epam.reportportal.service.ReportPortalClient; +import com.epam.reportportal.util.test.CommonUtils; +import com.epam.ta.reportportal.ws.model.ParameterResource; +import com.epam.ta.reportportal.ws.model.StartTestItemRQ; +import com.intuit.karate.Results; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.ArgumentCaptor; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.epam.reportportal.karate.utils.TestUtils.*; +import static com.epam.reportportal.utils.ParameterUtils.NULL_VALUE; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.*; + +public class NullValueExamplesTest { + private static final String TEST_FEATURE = "classpath:feature/null_examples.feature"; + private final String featureId = CommonUtils.namedId("feature_"); + private final List exampleIds = Stream.generate(() -> CommonUtils.namedId("example_")).limit(1).collect(Collectors.toList()); + private final List>> stepIds = exampleIds.stream() + .map(e -> Pair.of(e, Stream.generate(() -> CommonUtils.namedId("step_")).limit(1).collect(Collectors.toList()))) + .collect(Collectors.toList()); + + private final ReportPortalClient client = mock(ReportPortalClient.class); + private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor()); + + @BeforeEach + public void setupMock() { + mockLaunch(client, null, featureId, stepIds); + mockBatchLogging(client); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + public void test_examples_null_value(boolean report) { + Results results; + if (report) { + results = TestUtils.runAsReport(rp, TEST_FEATURE); + } else { + results = TestUtils.runAsHook(rp, TEST_FEATURE); + } + assertThat(results.getFailCount(), equalTo(0)); + + ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client, times(1)).startTestItem(captor.capture()); + verify(client, times(1)).startTestItem(same(featureId), captor.capture()); + verify(client, times(1)).startTestItem(same(exampleIds.get(0)), captor.capture()); + + List items = captor.getAllValues(); + assertThat(items, hasSize(3)); + + StartTestItemRQ firstScenarioRq = items.get(1); + List firstParameters = firstScenarioRq.getParameters(); + assertThat(firstParameters, hasSize(1)); + + assertThat( + firstParameters.stream().map(p -> p.getKey() + ":" + p.getValue()).collect(Collectors.toSet()), + hasItem("vara:" + NULL_VALUE) + ); + } +} diff --git a/src/test/java/com/epam/reportportal/karate/parameters/TableParametersTest.java b/src/test/java/com/epam/reportportal/karate/parameters/TableParametersTest.java index 4784329..47c32c3 100644 --- a/src/test/java/com/epam/reportportal/karate/parameters/TableParametersTest.java +++ b/src/test/java/com/epam/reportportal/karate/parameters/TableParametersTest.java @@ -36,8 +36,8 @@ import static com.epam.reportportal.karate.utils.TestUtils.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.startsWith; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.*; diff --git a/src/test/java/com/epam/reportportal/karate/retry/RetryFailedTest.java b/src/test/java/com/epam/reportportal/karate/retry/RetryFailedTest.java index 1c5b591..0ecfec6 100644 --- a/src/test/java/com/epam/reportportal/karate/retry/RetryFailedTest.java +++ b/src/test/java/com/epam/reportportal/karate/retry/RetryFailedTest.java @@ -36,8 +36,8 @@ import static com.epam.reportportal.karate.utils.TestUtils.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -import static org.mockito.Mockito.any; import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; public class RetryFailedTest { private static final String TEST_FEATURE = "classpath:feature/simple_failed.feature"; @@ -46,7 +46,8 @@ public class RetryFailedTest { private final List scenarioIds = Stream.generate(() -> CommonUtils.namedId("scenario_")).limit(2).collect(Collectors.toList()); private final List stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(6).collect(Collectors.toList()); - private final List>> scenarioSteps = Stream.of(Pair.of(scenarioIds.get(0), stepIds.subList(0, 3)), + private final List>> scenarioSteps = Stream.of( + Pair.of(scenarioIds.get(0), stepIds.subList(0, 3)), Pair.of(scenarioIds.get(1), stepIds.subList(3, 6)) ) .collect(Collectors.toList()); diff --git a/src/test/java/com/epam/reportportal/karate/status/OneExampleFailedTest.java b/src/test/java/com/epam/reportportal/karate/status/OneExampleFailedTest.java index 8dacfd8..65c5c2b 100644 --- a/src/test/java/com/epam/reportportal/karate/status/OneExampleFailedTest.java +++ b/src/test/java/com/epam/reportportal/karate/status/OneExampleFailedTest.java @@ -97,7 +97,8 @@ public void test_simple_one_step_failed(boolean report) { verifyStatus(Arrays.asList(firstExampleCaptor.getValue(), secondExampleCaptor.getValue()), ItemStatus.PASSED, ItemStatus.FAILED); - List steps = Arrays.asList(firstExampleFirstStepCaptor.getValue(), + List steps = Arrays.asList( + firstExampleFirstStepCaptor.getValue(), firstExampleSecondStepCaptor.getValue(), secondExampleFirstStepCaptor.getValue(), secondExampleSecondStepCaptor.getValue() diff --git a/src/test/java/com/epam/reportportal/karate/status/OneExampleWithBackgroundFailedTest.java b/src/test/java/com/epam/reportportal/karate/status/OneExampleWithBackgroundFailedTest.java index c630aa7..e066b6d 100644 --- a/src/test/java/com/epam/reportportal/karate/status/OneExampleWithBackgroundFailedTest.java +++ b/src/test/java/com/epam/reportportal/karate/status/OneExampleWithBackgroundFailedTest.java @@ -50,10 +50,7 @@ public class OneExampleWithBackgroundFailedTest { .map(e -> Pair.of(e, Stream.generate(() -> CommonUtils.namedId("step_")).limit(3).collect(Collectors.toList()))) .collect(Collectors.toList()); private final List> nestedSteps = Arrays.asList( - Pair.of( - stepIds.get(0).getValue().get(0), - CommonUtils.namedId("nested_step_") - ), + Pair.of(stepIds.get(0).getValue().get(0), CommonUtils.namedId("nested_step_")), Pair.of(stepIds.get(1).getValue().get(0), CommonUtils.namedId("nested_step_")) ); diff --git a/src/test/java/com/epam/reportportal/karate/timing/SimpleTimingTest.java b/src/test/java/com/epam/reportportal/karate/timing/SimpleTimingTest.java index c71d24d..9ed2d16 100644 --- a/src/test/java/com/epam/reportportal/karate/timing/SimpleTimingTest.java +++ b/src/test/java/com/epam/reportportal/karate/timing/SimpleTimingTest.java @@ -28,6 +28,7 @@ import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; +import java.util.Date; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -79,13 +80,13 @@ public void test_each_item_has_correct_start_date(boolean report) { assertThat( "Launch start time is greater than Feature start time.", - featureRq.getStartTime(), - greaterThanOrEqualTo(launchRq.getStartTime()) + (Date) featureRq.getStartTime(), + greaterThanOrEqualTo((Date) launchRq.getStartTime()) ); assertThat( "Feature start time is greater than Scenario start time.", - scenarioRq.getStartTime(), - greaterThanOrEqualTo(featureRq.getStartTime()) + (Date) scenarioRq.getStartTime(), + greaterThanOrEqualTo((Date) featureRq.getStartTime()) ); List steps = stepCaptor.getAllValues(); @@ -98,18 +99,18 @@ public void test_each_item_has_correct_start_date(boolean report) { assertThat( "Scenario start time is greater than Step start time.", - firstStep.getStartTime(), - greaterThanOrEqualTo(scenarioRq.getStartTime()) + (Date) firstStep.getStartTime(), + greaterThanOrEqualTo((Date) scenarioRq.getStartTime()) ); assertThat( "First Step start time is greater or equal than Second Step start time.", - secondStep.getStartTime(), - greaterThan(firstStep.getStartTime()) + (Date) secondStep.getStartTime(), + greaterThan((Date) firstStep.getStartTime()) ); assertThat( "Second Step start time is greater or equal than Third Step start time.", - thirdStep.getStartTime(), - greaterThan(secondStep.getStartTime()) + (Date) thirdStep.getStartTime(), + greaterThan((Date) secondStep.getStartTime()) ); } } diff --git a/src/test/java/com/epam/reportportal/karate/utils/TestUtils.java b/src/test/java/com/epam/reportportal/karate/utils/TestUtils.java index c1b36ef..e847ade 100644 --- a/src/test/java/com/epam/reportportal/karate/utils/TestUtils.java +++ b/src/test/java/com/epam/reportportal/karate/utils/TestUtils.java @@ -33,13 +33,13 @@ import com.intuit.karate.Results; import com.intuit.karate.Runner; import io.reactivex.Maybe; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import okhttp3.MultipartBody; import okio.Buffer; import org.apache.commons.lang3.tuple.Pair; import org.mockito.stubbing.Answer; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.io.IOException; import java.util.*; import java.util.concurrent.ExecutorService; diff --git a/src/test/resources/feature/null_examples.feature b/src/test/resources/feature/null_examples.feature new file mode 100644 index 0000000..e67efd5 --- /dev/null +++ b/src/test/resources/feature/null_examples.feature @@ -0,0 +1,8 @@ +Feature: a test with null value in examples + + Scenario Outline: Verify example null value + Then assert vara == null + + Examples: + | vara! | + | null |