diff --git a/src/main/java/com/epam/reportportal/karate/ReportPortalPublisher.java b/src/main/java/com/epam/reportportal/karate/ReportPortalPublisher.java index 074ee59..9d077c8 100644 --- a/src/main/java/com/epam/reportportal/karate/ReportPortalPublisher.java +++ b/src/main/java/com/epam/reportportal/karate/ReportPortalPublisher.java @@ -59,6 +59,7 @@ public class ReportPortalPublisher { public static final String EXAMPLE_CODE_REFERENCE_PATTERN = "%s/[EXAMPLE:%s%s]"; public static final String VARIABLE_PATTERN = "(?:(?<=#\\()%1$s(?=\\)))|(?:(?<=[\\s=+-/*<>(]|^)%1$s(?=[\\s=+-/*<>)]|(?:\\r?\\n)|$))"; + public static final String MARKDOWN_DELIMITER_PATTERN = "%s\n\n---\n\n%s"; private static final Logger LOGGER = LoggerFactory.getLogger(ReportPortalPublisher.class); private final Map> featureIdMap = new HashMap<>(); @@ -213,43 +214,28 @@ private Set toAttributes(@Nullable List tags) { */ @Nonnull protected StartTestItemRQ buildStartFeatureRq(@Nonnull FeatureResult featureResult) { - StartTestItemRQ rq = buildStartTestItemRq(String.valueOf(featureResult.toCucumberJson().get("name")), - Calendar.getInstance().getTime(), - ItemType.STORY); Feature feature = featureResult.getFeature(); + StartTestItemRQ rq = buildStartTestItemRq(feature.getName(), Calendar.getInstance().getTime(), ItemType.STORY); rq.setAttributes(toAttributes(feature.getTags())); - return rq; - } - - @Nullable - private List getParameters(@Nonnull Scenario scenario) { - if (scenario.getExampleIndex() < 0) { - return null; + String featurePath = feature.getResource().getUri().toString(); + String description = feature.getDescription(); + if (isNotBlank(description)) { + rq.setDescription(String.format(MARKDOWN_DELIMITER_PATTERN, featurePath, description)); + } else { + rq.setDescription(featurePath); } - return scenario.getExampleData().entrySet().stream().map(e -> { - ParameterResource parameterResource = new ParameterResource(); - parameterResource.setKey(e.getKey()); - parameterResource.setValue(ofNullable(e.getValue()).map(Object::toString).orElse(NULL_VALUE)); - return parameterResource; - }).collect(Collectors.toList()); + return rq; } /** - * Build ReportPortal request for start Scenario event + * Start sending feature data to ReportPortal. * - * @param scenarioResult Karate's ScenarioResult object instance - * @return request to ReportPortal + * @param featureResult feature result */ - protected StartTestItemRQ buildStartScenarioRq(@Nonnull ScenarioResult scenarioResult) { - StartTestItemRQ rq = buildStartTestItemRq(scenarioResult.getScenario().getName(), - Calendar.getInstance().getTime(), - ItemType.STEP); - Scenario scenario = scenarioResult.getScenario(); - rq.setCodeRef(getCodeRef(scenario)); - rq.setTestCaseId(ofNullable(getTestCaseId(scenario)).map(TestCaseIdEntry::getId).orElse(null)); - rq.setAttributes(toAttributes(scenario.getTags())); - rq.setParameters(getParameters(scenario)); - return rq; + public void startFeature(@Nonnull FeatureResult featureResult) { + StartTestItemRQ rq = buildStartFeatureRq(featureResult); + Maybe featureId = launch.get().startTestItem(rq); + featureIdMap.put(featureResult.getCallNameForReport(), featureId); } /** @@ -267,17 +253,6 @@ protected FinishTestItemRQ buildFinishTestItemRq(@Nonnull Date endTime, return rq; } - /** - * Start sending feature data to ReportPortal. - * - * @param featureResult feature result - */ - public void startFeature(@Nonnull FeatureResult featureResult) { - StartTestItemRQ rq = buildStartFeatureRq(featureResult); - Maybe featureId = launch.get().startTestItem(rq); - featureIdMap.put(featureResult.getCallNameForReport(), featureId); - } - /** * Finish sending feature data to ReportPortal * @@ -308,6 +283,41 @@ public void finishFeature(FeatureResult featureResult) { launch.get().finishTestItem(featureIdMap.remove(featureResult.getCallNameForReport()), rq); } + @Nullable + private List getParameters(@Nonnull Scenario scenario) { + if (scenario.getExampleIndex() < 0) { + return null; + } + return scenario.getExampleData().entrySet().stream().map(e -> { + ParameterResource parameterResource = new ParameterResource(); + parameterResource.setKey(e.getKey()); + parameterResource.setValue(ofNullable(e.getValue()).map(Object::toString).orElse(NULL_VALUE)); + return parameterResource; + }).collect(Collectors.toList()); + } + + /** + * Build ReportPortal request for start Scenario event + * + * @param scenarioResult Karate's ScenarioResult object instance + * @return request to ReportPortal + */ + protected StartTestItemRQ buildStartScenarioRq(@Nonnull ScenarioResult scenarioResult) { + StartTestItemRQ rq = buildStartTestItemRq(scenarioResult.getScenario().getName(), + Calendar.getInstance().getTime(), + ItemType.STEP); + Scenario scenario = scenarioResult.getScenario(); + rq.setCodeRef(getCodeRef(scenario)); + rq.setTestCaseId(ofNullable(getTestCaseId(scenario)).map(TestCaseIdEntry::getId).orElse(null)); + rq.setAttributes(toAttributes(scenario.getTags())); + rq.setParameters(getParameters(scenario)); + String description = scenario.getDescription(); + if (isNotBlank(description)) { + rq.setDescription(description); + } + return rq; + } + /** * Start sending scenario data to ReportPortal * diff --git a/src/test/java/com/epam/reportportal/karate/attributes/SystemAttributesTest.java b/src/test/java/com/epam/reportportal/karate/attributes/SystemAttributesTest.java index 7ea6812..a5cb85e 100644 --- a/src/test/java/com/epam/reportportal/karate/attributes/SystemAttributesTest.java +++ b/src/test/java/com/epam/reportportal/karate/attributes/SystemAttributesTest.java @@ -32,7 +32,6 @@ import java.util.stream.Stream; import static com.epam.reportportal.karate.utils.TestUtils.*; -import static com.epam.reportportal.karate.utils.TestUtils.mockBatchLogging; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.mock; diff --git a/src/test/java/com/epam/reportportal/karate/background/BackgroundExamplesTest.java b/src/test/java/com/epam/reportportal/karate/background/BackgroundExamplesTest.java index e29f9ab..bdf0b09 100644 --- a/src/test/java/com/epam/reportportal/karate/background/BackgroundExamplesTest.java +++ b/src/test/java/com/epam/reportportal/karate/background/BackgroundExamplesTest.java @@ -79,7 +79,7 @@ public void test_background_steps() { .filter(s -> s.getName().startsWith(Background.KEYWORD)).collect(Collectors.toList()); assertThat(secondBackgroundSteps, hasSize(1)); - Stream.concat(firstBackgroundSteps.stream(), secondBackgroundSteps.stream()).forEach(backgroundStep ->{ + Stream.concat(firstBackgroundSteps.stream(), secondBackgroundSteps.stream()).forEach(backgroundStep -> { assertThat(backgroundStep.getName(), equalTo(Background.KEYWORD)); // No name for Background in Karate assertThat(backgroundStep.isHasStats(), equalTo(Boolean.FALSE)); assertThat(backgroundStep.getStartTime(), notNullValue()); diff --git a/src/test/java/com/epam/reportportal/karate/background/BackgroundTest.java b/src/test/java/com/epam/reportportal/karate/background/BackgroundTest.java index 785c3be..fa81516 100644 --- a/src/test/java/com/epam/reportportal/karate/background/BackgroundTest.java +++ b/src/test/java/com/epam/reportportal/karate/background/BackgroundTest.java @@ -48,7 +48,7 @@ public void test_background_steps() { ArgumentCaptor captor = ArgumentCaptor.forClass(StartTestItemRQ.class); verify(client).startTestItem(captor.capture()); - verify(client, times(1)).startTestItem(same(featureId), captor.capture()); + verify(client).startTestItem(same(featureId), captor.capture()); ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); verify(client, times(3)).startTestItem(same(scenarioId), stepCaptor.capture()); ArgumentCaptor nestedStepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); diff --git a/src/test/java/com/epam/reportportal/karate/coderef/ScenarioCodeRefTest.java b/src/test/java/com/epam/reportportal/karate/coderef/ScenarioCodeRefTest.java index b7b047a..fe0c31e 100644 --- a/src/test/java/com/epam/reportportal/karate/coderef/ScenarioCodeRefTest.java +++ b/src/test/java/com/epam/reportportal/karate/coderef/ScenarioCodeRefTest.java @@ -12,7 +12,6 @@ import java.util.List; import java.util.stream.Collectors; -import java.util.stream.IntStream; import java.util.stream.Stream; import static com.epam.reportportal.karate.utils.TestUtils.*; @@ -43,25 +42,22 @@ public void test_scenario_code_reference() { var results = TestUtils.runAsReport(rp, "classpath:feature/simple.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(3)).startTestItem(same(scenarioId), captor.capture()); + ArgumentCaptor featureCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client).startTestItem(featureCaptor.capture()); + ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client).startTestItem(same(featureId), scenarioCaptor.capture()); + ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client, times(3)).startTestItem(same(scenarioId), stepCaptor.capture()); - List items = captor.getAllValues(); - assertThat(items, hasSize(5)); - - StartTestItemRQ featureRq = items.get(0); - StartTestItemRQ scenarioRq = items.get(1); + StartTestItemRQ featureRq = featureCaptor.getValue(); + StartTestItemRQ scenarioRq = scenarioCaptor.getValue(); assertThat(featureRq.getType(), allOf(notNullValue(), equalTo(ItemType.STORY.name()))); assertThat(scenarioRq.getType(), allOf(notNullValue(), equalTo(ItemType.STEP.name()))); assertThat(scenarioRq.getCodeRef(), allOf(notNullValue(), equalTo(SIMPLE_CODE_REFERENCE))); - List stepRqs = items.subList(2, items.size()); - IntStream.range(0, stepRqs.size()).forEach(i -> { - StartTestItemRQ step = stepRqs.get(i); + stepCaptor.getAllValues().forEach(step -> { assertThat(step.getType(), allOf(notNullValue(), equalTo(ItemType.STEP.name()))); assertThat(step.isHasStats(), equalTo(Boolean.FALSE)); }); diff --git a/src/test/java/com/epam/reportportal/karate/description/NoDescriptionTest.java b/src/test/java/com/epam/reportportal/karate/description/NoDescriptionTest.java new file mode 100644 index 0000000..05b4b97 --- /dev/null +++ b/src/test/java/com/epam/reportportal/karate/description/NoDescriptionTest.java @@ -0,0 +1,58 @@ +package com.epam.reportportal.karate.description; + +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.StartTestItemRQ; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +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 org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.*; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.*; + +public class NoDescriptionTest { + 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, null, featureId, scenarioId, stepIds); + mockBatchLogging(client); + } + + @Test + public void test_description_for_all_possible_items() { + var results = TestUtils.runAsReport(rp, "classpath:feature/simple.feature"); + assertThat(results.getFailCount(), equalTo(0)); + + ArgumentCaptor featureCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client).startTestItem(featureCaptor.capture()); + ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client).startTestItem(same(featureId), scenarioCaptor.capture()); + ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client, times(3)).startTestItem(same(scenarioId), stepCaptor.capture()); + + StartTestItemRQ featureStart = featureCaptor.getValue(); + assertThat(featureStart.getDescription(), endsWith("feature/simple.feature")); + + StartTestItemRQ scenarioStart = scenarioCaptor.getValue(); + assertThat(scenarioStart.getDescription(), nullValue()); + + stepCaptor.getAllValues().forEach(step -> assertThat(step.getDescription(), nullValue())); + } +} diff --git a/src/test/java/com/epam/reportportal/karate/description/SimpleDescriptionTest.java b/src/test/java/com/epam/reportportal/karate/description/SimpleDescriptionTest.java new file mode 100644 index 0000000..d88c135 --- /dev/null +++ b/src/test/java/com/epam/reportportal/karate/description/SimpleDescriptionTest.java @@ -0,0 +1,68 @@ +package com.epam.reportportal.karate.description; + +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.StartTestItemRQ; +import com.intuit.karate.core.Background; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +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 org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.*; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.*; + +public class SimpleDescriptionTest { + 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 List> nestedStepIds = stepIds.stream() + .map(id -> Pair.of(id, CommonUtils.namedId("nested_step_"))).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, scenarioId, stepIds); + mockNestedSteps(client, nestedStepIds); + mockBatchLogging(client); + } + + @Test + public void test_description_for_all_possible_items() { + var results = TestUtils.runAsReport(rp, "classpath:feature/description.feature"); + assertThat(results.getFailCount(), equalTo(0)); + + ArgumentCaptor featureCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client).startTestItem(featureCaptor.capture()); + ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client).startTestItem(same(featureId), scenarioCaptor.capture()); + ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client, times(3)).startTestItem(same(scenarioId), stepCaptor.capture()); + + StartTestItemRQ featureStart = featureCaptor.getValue(); + assertThat(featureStart.getDescription(), endsWith("feature/description.feature\n\n---\n\nThis is my Feature description.")); + + StartTestItemRQ scenarioStart = scenarioCaptor.getValue(); + assertThat(scenarioStart.getDescription(), equalTo("This is my Scenario description.")); + + List backgroundSteps = stepCaptor.getAllValues().stream() + .filter(s -> s.getName().startsWith(Background.KEYWORD)).collect(Collectors.toList()); + assertThat(backgroundSteps, hasSize(1)); + StartTestItemRQ backgroundStep = backgroundSteps.get(0); + assertThat("No support of Background description in Karate yet. But this is a part of Gherkin standard.", + backgroundStep.getDescription(), nullValue()); + } +} diff --git a/src/test/java/com/epam/reportportal/karate/name/SimpleItemNameTest.java b/src/test/java/com/epam/reportportal/karate/name/SimpleItemNameTest.java new file mode 100644 index 0000000..a12ee62 --- /dev/null +++ b/src/test/java/com/epam/reportportal/karate/name/SimpleItemNameTest.java @@ -0,0 +1,65 @@ +package com.epam.reportportal.karate.name; + +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.StartTestItemRQ; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static com.epam.reportportal.karate.utils.TestUtils.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.*; + +public class SimpleItemNameTest { + 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, null, featureId, scenarioId, stepIds); + mockBatchLogging(client); + } + + @Test + public void test_scenario_code_reference() { + var results = TestUtils.runAsReport(rp, "classpath:feature/simple.feature"); + assertThat(results.getFailCount(), equalTo(0)); + + ArgumentCaptor featureCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client, times(1)).startTestItem(featureCaptor.capture()); + ArgumentCaptor scenarioCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client, times(1)).startTestItem(same(featureId), scenarioCaptor.capture()); + ArgumentCaptor stepCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client, times(3)).startTestItem(same(scenarioId), stepCaptor.capture()); + + StartTestItemRQ featureRq = featureCaptor.getValue(); + StartTestItemRQ scenarioRq = scenarioCaptor.getValue(); + + assertThat(featureRq.getName(), allOf(notNullValue(), equalTo("the very basic test to run by Karate"))); + + assertThat(scenarioRq.getName(), allOf(notNullValue(), equalTo("Verify math"))); + + List stepRqs = stepCaptor.getAllValues(); + String[] stepNames = new String[]{"Given def four = 4", "When def actualFour = 2 * 2", + "Then assert actualFour == four"}; + IntStream.range(0, stepRqs.size()).forEach(i -> { + StartTestItemRQ step = stepRqs.get(i); + assertThat(step.getName(), allOf(notNullValue(), equalTo(stepNames[i]))); + }); + } +} 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 d9185e9..5281922 100644 --- a/src/test/java/com/epam/reportportal/karate/parameters/ExamplesStepParametersTest.java +++ b/src/test/java/com/epam/reportportal/karate/parameters/ExamplesStepParametersTest.java @@ -24,8 +24,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.*; import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.Matchers.*; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.*; 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 de95fc0..7ed7a89 100644 --- a/src/test/java/com/epam/reportportal/karate/parameters/TableParametersTest.java +++ b/src/test/java/com/epam/reportportal/karate/parameters/TableParametersTest.java @@ -13,14 +13,13 @@ import org.mockito.ArgumentCaptor; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import static com.epam.reportportal.karate.utils.TestUtils.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.Matchers.*; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.*; diff --git a/src/test/resources/feature/description.feature b/src/test/resources/feature/description.feature new file mode 100644 index 0000000..818e8da --- /dev/null +++ b/src/test/resources/feature/description.feature @@ -0,0 +1,16 @@ +Feature: the test to show item description reporting + + This is my Feature description. + + Background: Set variable + + This is my Background description. + + Given def four = 4 + + Scenario: Verify math + + This is my Scenario description. + + When def actualFour = 2 * 2 + Then assert actualFour == four