From 07d589b410afb1a641ea311545032d82bb2c76c5 Mon Sep 17 00:00:00 2001 From: Artem_Oliinyk Date: Thu, 14 Mar 2024 21:54:50 +0100 Subject: [PATCH 1/9] [Cucumber_4] Implemented logic that appends an error to the scenario and step description. --- .../cucumber/AbstractReporter.java | 55 +++++++++++++++---- .../reportportal/cucumber/FailedTest.java | 48 ++++++++++++++++ 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java b/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java index fb50a43..fc36dd2 100644 --- a/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java +++ b/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java @@ -47,6 +47,8 @@ import gherkin.pickles.PickleTag; import io.reactivex.Maybe; import okhttp3.MediaType; + +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,6 +68,7 @@ import static com.epam.reportportal.cucumber.Utils.*; import static com.epam.reportportal.cucumber.util.ItemTreeUtils.createKey; import static com.epam.reportportal.cucumber.util.ItemTreeUtils.retrieveLeaf; +import static java.lang.String.format; import static java.util.Optional.of; import static java.util.Optional.ofNullable; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -89,6 +92,8 @@ public abstract class AbstractReporter implements ConcurrentEventListener { private static final String FILE_PREFIX = "file:"; private static final String HOOK_ = "Hook: "; private static final String DOCSTRING_DECORATOR = "\n\"\"\"\n"; + private static final String ERROR_FORMAT = "Error:\n%s"; + private static final String DESCRIPTION_ERROR_FORMAT = "%s\n" + ERROR_FORMAT; public static final TestItemTree ITEM_TREE = new TestItemTree(); private static volatile ReportPortal REPORT_PORTAL = ReportPortal.builder().build(); @@ -108,6 +113,11 @@ public abstract class AbstractReporter implements ConcurrentEventListener { // End of feature occurs once launch is finished. private final Map featureEndTime = new ConcurrentHashMap<>(); + /** + * This map uses to record the description of the scenario and the step to append the error to the description. + */ + private final Map descriptionsMap = new ConcurrentHashMap<>(); + public static ReportPortal getReportPortal() { return REPORT_PORTAL; } @@ -239,10 +249,10 @@ protected void beforeScenario(RunningContext.FeatureContext featureContext, Runn AbstractReporter.COLON_INFIX, scenarioContext.getTestCase().getName() ); - Maybe id = startScenario(featureContext.getFeatureId(), - buildStartScenarioRequest(scenarioContext.getTestCase(), scenarioName, featureContext.getUri(), scenarioContext.getLine()) - ); + StartTestItemRQ startTestItemRQ = buildStartScenarioRequest(scenarioContext.getTestCase(), scenarioName, featureContext.getUri(), scenarioContext.getLine()); + Maybe id = startScenario(featureContext.getFeatureId(), startTestItemRQ); scenarioContext.setId(id); + descriptionsMap.put(scenarioContext.getId().blockingGet(), ofNullable(startTestItemRQ.getDescription()).orElse(StringUtils.EMPTY)); if (launch.get().getParameters().isCallbackReportingEnabled()) { addToTree(featureContext, scenarioContext); } @@ -280,13 +290,32 @@ protected ItemStatus mapItemStatus(@Nullable Result.Type status) { @Nonnull @SuppressWarnings("unused") protected FinishTestItemRQ buildFinishTestItemRequest(@Nonnull Maybe itemId, @Nullable Date finishTime, - @Nullable ItemStatus status) { + @Nullable ItemStatus status, @Nullable Throwable error) { FinishTestItemRQ rq = new FinishTestItemRQ(); + if (status == ItemStatus.FAILED) { + Optional currentDescription = Optional.ofNullable(descriptionsMap.get(itemId.blockingGet())); + currentDescription.flatMap(description -> Optional.ofNullable(error) + .map(errorMessage -> resolveDescriptionErrorMessage(description, errorMessage))) + .ifPresent(rq::setDescription); + } ofNullable(status).ifPresent(s -> rq.setStatus(s.name())); rq.setEndTime(ofNullable(finishTime).orElse(Calendar.getInstance().getTime())); return rq; } + /** + * Resolve description + * @param currentDescription Current description + * @param error Error message + * @return Description with error + */ + private String resolveDescriptionErrorMessage(String currentDescription, Throwable error) { + return Optional.ofNullable(currentDescription) + .filter(StringUtils::isNotBlank) + .map(description -> format(DESCRIPTION_ERROR_FORMAT, currentDescription, error)) + .orElse(format(ERROR_FORMAT, error)); + } + /** * Finish a test item with specified status * @@ -294,13 +323,13 @@ protected FinishTestItemRQ buildFinishTestItemRequest(@Nonnull Maybe ite * @param status the status of the item * @return a date and time object of the finish event */ - protected Date finishTestItem(Maybe itemId, Result.Type status) { + protected Date finishTestItem(Maybe itemId, Result.Type status, @Nullable Throwable error) { if (itemId == null) { LOGGER.error("BUG: Trying to finish unspecified test item."); return null; } - FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, null, mapItemStatus(status)); + FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, null, mapItemStatus(status), error); //noinspection ReactiveStreamsUnusedPublisher launch.get().finishTestItem(itemId, rq); return rq.getEndTime(); @@ -312,7 +341,7 @@ protected Date finishTestItem(Maybe itemId, Result.Type status) { * @param itemId an ID of the item */ protected void finishTestItem(Maybe itemId) { - finishTestItem(itemId, null); + finishTestItem(itemId, null, null); } private void removeFromTree(RunningContext.FeatureContext featureContext, RunningContext.ScenarioContext scenarioContext) { @@ -330,7 +359,7 @@ protected void afterScenario(TestCaseFinished event) { RunningContext.ScenarioContext context = getCurrentScenarioContext(); String featureUri = context.getFeatureUri(); currentScenarioContextMap.remove(Pair.of(context.getLine(), featureUri)); - Date endTime = finishTestItem(context.getId(), event.result.getStatus()); + Date endTime = finishTestItem(context.getId(), event.result.getStatus(), event.result.getError()); featureEndTime.put(featureUri, endTime); currentScenarioContext.remove(); removeFromTree(currentFeatureContextMap.get(context.getFeatureUri()), context); @@ -436,7 +465,9 @@ protected void beforeStep(TestStep testStep) { context.setCurrentStepId(stepId); String stepText = step.getText(); context.setCurrentText(stepText); - + if (rq.isHasStats()) { + descriptionsMap.put(stepId.blockingGet(), ofNullable(rq.getDescription()).orElse(StringUtils.EMPTY)); + } if (launch.get().getParameters().isCallbackReportingEnabled()) { addToTree(context, stepText, stepId); } @@ -450,7 +481,7 @@ protected void beforeStep(TestStep testStep) { protected void afterStep(Result result) { reportResult(result, null); RunningContext.ScenarioContext context = getCurrentScenarioContext(); - finishTestItem(context.getCurrentStepId(), result.getStatus()); + finishTestItem(context.getCurrentStepId(), result.getStatus(), result.getError()); context.setCurrentStepId(null); } @@ -501,7 +532,7 @@ protected void beforeHooks(HookType hookType) { */ protected void afterHooks(HookType hookType) { RunningContext.ScenarioContext context = getCurrentScenarioContext(); - finishTestItem(context.getHookStepId(), context.getHookStatus()); + finishTestItem(context.getHookStepId(), context.getHookStatus(), null); context.setHookStepId(null); if (hookType == HookType.AfterStep) { removeFromTree(context, context.getCurrentText()); @@ -628,7 +659,7 @@ protected void finishFeature(Maybe itemId, Date dateTime) { LOGGER.error("BUG: Trying to finish unspecified test item."); return; } - FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, dateTime, null); + FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, dateTime, null, null); //noinspection ReactiveStreamsUnusedPublisher launch.get().finishTestItem(itemId, rq); } diff --git a/src/test/java/com/epam/reportportal/cucumber/FailedTest.java b/src/test/java/com/epam/reportportal/cucumber/FailedTest.java index b7292c9..49ff98f 100644 --- a/src/test/java/com/epam/reportportal/cucumber/FailedTest.java +++ b/src/test/java/com/epam/reportportal/cucumber/FailedTest.java @@ -44,6 +44,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.not; import static org.mockito.Mockito.*; /** @@ -52,6 +53,10 @@ public class FailedTest { private static final String EXPECTED_ERROR = "java.lang.IllegalStateException: " + FailedSteps.ERROR_MESSAGE; + private static final String ERROR_LOG_TEXT = "Error:\n" + EXPECTED_ERROR; + private static final String DESCRIPTION_ERROR_LOG_TEXT = + "file:src/test/resources/features/FailedScenario.feature\n" + + ERROR_LOG_TEXT; @CucumberOptions(features = "src/test/resources/features/FailedScenario.feature", glue = { "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", @@ -136,4 +141,47 @@ public void verify_failed_step_reporting_step_reporter() { SaveLogRQ expectedError = expectedErrorList.get(0); assertThat(expectedError.getItemUuid(), equalTo(stepId)); } + + @Test + @SuppressWarnings("unchecked") + public void verify_failed_nested_step_description_scenario_reporter() { + TestUtils.runTests(FailedScenarioReporter.class); + + verify(client).startTestItem(any()); + verify(client).startTestItem(same(suiteId), any()); + verify(client).startTestItem(same(testId), any()); + verify(client).startTestItem(same(stepId), any()); + ArgumentCaptor finishCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(client).finishTestItem(same(nestedStepId), finishCaptor.capture()); + verify(client).finishTestItem(same(stepId), any()); + verify(client).finishTestItem(same(testId), finishCaptor.capture()); + + List finishRqs = finishCaptor.getAllValues(); + finishRqs.subList(0, finishRqs.size() - 1).forEach(e -> assertThat(e.getStatus(), equalTo(ItemStatus.FAILED.name()))); + + FinishTestItemRQ step = finishRqs.get(0); + assertThat(step.getDescription(), not(equalTo(ERROR_LOG_TEXT))); + assertThat(step.getDescription(), not(equalTo(DESCRIPTION_ERROR_LOG_TEXT))); + } + + @Test + @SuppressWarnings("unchecked") + public void verify_failed_step_description_step_reporter() { + TestUtils.runTests(FailedStepReporter.class); + + verify(client).startTestItem(any()); + verify(client).startTestItem(same(suiteId), any()); + verify(client).startTestItem(same(testId), any()); + ArgumentCaptor finishCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(client).finishTestItem(same(stepId), finishCaptor.capture()); + verify(client).finishTestItem(same(testId), finishCaptor.capture()); + + List finishRqs = finishCaptor.getAllValues(); + finishRqs.forEach(e -> assertThat(e.getStatus(), equalTo(ItemStatus.FAILED.name()))); + + FinishTestItemRQ step = finishRqs.get(0); + assertThat(step.getDescription(), equalTo(ERROR_LOG_TEXT)); + FinishTestItemRQ test = finishRqs.get(1); + assertThat(test.getDescription(), equalTo(DESCRIPTION_ERROR_LOG_TEXT)); + } } From 5fed7c6f1eea285102e0b2e94c7d89781fda509f Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Thu, 11 Apr 2024 12:56:01 +0300 Subject: [PATCH 2/9] Action version update --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5dc7415..05f4391 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: java-version: '8' - name: Setup git credentials - uses: oleksiyrudenko/gha-git-credentials@v2.1.1 + uses: oleksiyrudenko/gha-git-credentials@v2-latest with: name: 'reportportal.io' email: 'support@reportportal.io' From b9c273d2bcc94cad5b5370f3f1cf7b87945ccbb1 Mon Sep 17 00:00:00 2001 From: Artem_Oliinyk Date: Fri, 12 Apr 2024 16:44:20 +0200 Subject: [PATCH 3/9] [Cucumber_4] Fixed issues mentioned in PR related to last error log. --- .../cucumber/AbstractReporter.java | 65 ++++++++++++------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java b/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java index 13287cd..8369dc1 100644 --- a/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java +++ b/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java @@ -116,6 +116,10 @@ public abstract class AbstractReporter implements ConcurrentEventListener { * This map uses to record the description of the scenario and the step to append the error to the description. */ private final Map descriptionsMap = new ConcurrentHashMap<>(); + /** + * This map uses to record errors to append to the description. + */ + private final Map errorMap = new ConcurrentHashMap<>(); public static ReportPortal getReportPortal() { return REPORT_PORTAL; @@ -251,7 +255,7 @@ protected void beforeScenario(RunningContext.FeatureContext featureContext, Runn StartTestItemRQ startTestItemRQ = buildStartScenarioRequest(scenarioContext.getTestCase(), scenarioName, featureContext.getUri(), scenarioContext.getLine()); Maybe id = startScenario(featureContext.getFeatureId(), startTestItemRQ); scenarioContext.setId(id); - descriptionsMap.put(scenarioContext.getId().blockingGet(), ofNullable(startTestItemRQ.getDescription()).orElse(StringUtils.EMPTY)); + id.subscribe(scenarioId -> descriptionsMap.put(scenarioId, ofNullable(startTestItemRQ.getDescription()).orElse(StringUtils.EMPTY))); if (launch.get().getParameters().isCallbackReportingEnabled()) { addToTree(featureContext, scenarioContext); } @@ -288,18 +292,21 @@ protected ItemStatus mapItemStatus(@Nullable Result.Type status) { */ @Nonnull @SuppressWarnings("unused") - protected FinishTestItemRQ buildFinishTestItemRequest(@Nonnull Maybe itemId, @Nullable Date finishTime, - @Nullable ItemStatus status, @Nullable Throwable error) { - FinishTestItemRQ rq = new FinishTestItemRQ(); - if (status == ItemStatus.FAILED) { - Optional currentDescription = Optional.ofNullable(descriptionsMap.get(itemId.blockingGet())); - currentDescription.flatMap(description -> Optional.ofNullable(error) - .map(errorMessage -> resolveDescriptionErrorMessage(description, errorMessage))) - .ifPresent(rq::setDescription); - } - ofNullable(status).ifPresent(s -> rq.setStatus(s.name())); - rq.setEndTime(ofNullable(finishTime).orElse(Calendar.getInstance().getTime())); - return rq; + protected Maybe buildFinishTestItemRequest(@Nonnull Maybe itemId, @Nullable Date finishTime, + @Nullable ItemStatus status) { + return itemId.map(id -> { + FinishTestItemRQ rq = new FinishTestItemRQ(); + if (status == ItemStatus.FAILED) { + Optional currentDescription = Optional.ofNullable(descriptionsMap.get(itemId.blockingGet())); + Optional currentError = Optional.ofNullable(errorMap.get(itemId.blockingGet())); + currentDescription.flatMap(description -> currentError + .map(errorMessage -> resolveDescriptionErrorMessage(description, errorMessage))) + .ifPresent(rq::setDescription); + } + ofNullable(status).ifPresent(s -> rq.setStatus(s.name())); + rq.setEndTime(finishTime); + return rq; + }); } /** @@ -322,16 +329,17 @@ private String resolveDescriptionErrorMessage(String currentDescription, Throwab * @param status the status of the item * @return a date and time object of the finish event */ - protected Date finishTestItem(Maybe itemId, Result.Type status, @Nullable Throwable error) { + protected Date finishTestItem(Maybe itemId, Result.Type status) { if (itemId == null) { LOGGER.error("BUG: Trying to finish unspecified test item."); return null; } - FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, null, mapItemStatus(status), error); + Date endTime = Calendar.getInstance().getTime(); + Maybe rqMaybe = buildFinishTestItemRequest(itemId, endTime, mapItemStatus(status)); //noinspection ReactiveStreamsUnusedPublisher - launch.get().finishTestItem(itemId, rq); - return rq.getEndTime(); + rqMaybe.subscribe(rq -> launch.get().finishTestItem(itemId, rq)); + return endTime; } /** @@ -340,7 +348,7 @@ protected Date finishTestItem(Maybe itemId, Result.Type status, @Nullabl * @param itemId an ID of the item */ protected void finishTestItem(Maybe itemId) { - finishTestItem(itemId, null, null); + finishTestItem(itemId, null); } private void removeFromTree(RunningContext.FeatureContext featureContext, RunningContext.ScenarioContext scenarioContext) { @@ -358,7 +366,11 @@ protected void afterScenario(TestCaseFinished event) { RunningContext.ScenarioContext context = getCurrentScenarioContext(); String featureUri = context.getFeatureUri(); currentScenarioContextMap.remove(Pair.of(context.getLine(), featureUri)); - Date endTime = finishTestItem(context.getId(), event.result.getStatus(), event.result.getError()); + if (mapItemStatus(event.result.getStatus()) == ItemStatus.FAILED) { + Optional.ofNullable(event.result.getError()) + .ifPresent(error -> context.getId().subscribe(id -> errorMap.put(id, error))); + } + Date endTime = finishTestItem(context.getId(), event.result.getStatus()); featureEndTime.put(featureUri, endTime); currentScenarioContext.remove(); removeFromTree(currentFeatureContextMap.get(context.getFeatureUri()), context); @@ -465,7 +477,7 @@ protected void beforeStep(TestStep testStep) { String stepText = step.getText(); context.setCurrentText(stepText); if (rq.isHasStats()) { - descriptionsMap.put(stepId.blockingGet(), ofNullable(rq.getDescription()).orElse(StringUtils.EMPTY)); + stepId.subscribe(id -> descriptionsMap.put(id, ofNullable(rq.getDescription()).orElse(StringUtils.EMPTY))); } if (launch.get().getParameters().isCallbackReportingEnabled()) { addToTree(context, stepText, stepId); @@ -480,7 +492,11 @@ protected void beforeStep(TestStep testStep) { protected void afterStep(Result result) { reportResult(result, null); RunningContext.ScenarioContext context = getCurrentScenarioContext(); - finishTestItem(context.getCurrentStepId(), result.getStatus(), result.getError()); + if (mapItemStatus(result.getStatus()) == ItemStatus.FAILED){ + Optional.ofNullable(result.getError()) + .ifPresent(error -> context.getCurrentStepId().subscribe(id -> errorMap.put(id, error))); + } + finishTestItem(context.getCurrentStepId(), result.getStatus()); context.setCurrentStepId(null); } @@ -531,7 +547,7 @@ protected void beforeHooks(HookType hookType) { */ protected void afterHooks(HookType hookType) { RunningContext.ScenarioContext context = getCurrentScenarioContext(); - finishTestItem(context.getHookStepId(), context.getHookStatus(), null); + finishTestItem(context.getHookStepId(), context.getHookStatus()); context.setHookStepId(null); if (hookType == HookType.AfterStep) { removeFromTree(context, context.getCurrentText()); @@ -650,9 +666,10 @@ protected void finishFeature(Maybe itemId, Date dateTime) { LOGGER.error("BUG: Trying to finish unspecified test item."); return; } - FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, dateTime, null, null); + Date endTime = ofNullable(dateTime).orElse(Calendar.getInstance().getTime()); + Maybe rqMaybe = buildFinishTestItemRequest(itemId, endTime, null); //noinspection ReactiveStreamsUnusedPublisher - launch.get().finishTestItem(itemId, rq); + rqMaybe.subscribe(rq -> launch.get().finishTestItem(itemId, rq)); } private void removeFromTree(RunningContext.FeatureContext featureContext) { From 762a09a04a655d1e7409642e2c12a19ee1744516 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Thu, 18 Apr 2024 18:10:22 +0300 Subject: [PATCH 4/9] Client version update --- CHANGELOG.md | 2 ++ build.gradle | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 183d311..fc077ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +### Changed +- Client version updated on [5.2.14](https://github.com/reportportal/client-java/releases/tag/5.2.14), by @HardNorth ## [5.2.2] ### Changed diff --git a/build.gradle b/build.gradle index 2ab5bf4..d4a43c3 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ repositories { } dependencies { - api 'com.epam.reportportal:client-java:5.2.13' + api 'com.epam.reportportal:client-java:5.2.14' api "io.cucumber:cucumber-java:${project.cucumber_version}" implementation 'org.slf4j:slf4j-api:2.0.7' From 8de54050023b116dcc793e0e769e7e1ad4f06d0a Mon Sep 17 00:00:00 2001 From: Artem_Oliinyk Date: Tue, 30 Apr 2024 23:55:22 +0200 Subject: [PATCH 5/9] [Cucumber_4] Unit tests were fixed. --- .../com/epam/reportportal/cucumber/FailedTest.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/epam/reportportal/cucumber/FailedTest.java b/src/test/java/com/epam/reportportal/cucumber/FailedTest.java index 49ff98f..5c55032 100644 --- a/src/test/java/com/epam/reportportal/cucumber/FailedTest.java +++ b/src/test/java/com/epam/reportportal/cucumber/FailedTest.java @@ -42,9 +42,13 @@ import static com.epam.reportportal.cucumber.integration.util.TestUtils.filterLogs; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; import static org.mockito.Mockito.*; /** @@ -58,6 +62,10 @@ public class FailedTest { "file:src/test/resources/features/FailedScenario.feature\n" + ERROR_LOG_TEXT; + private static final Pair SCENARIO_CODE_REFERENCES_WITH_ERROR = Pair.of("file:", + "src/test/resources/features/FailedScenario.feature\n" + ERROR_LOG_TEXT + ); + @CucumberOptions(features = "src/test/resources/features/FailedScenario.feature", glue = { "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) @@ -161,7 +169,6 @@ public void verify_failed_nested_step_description_scenario_reporter() { FinishTestItemRQ step = finishRqs.get(0); assertThat(step.getDescription(), not(equalTo(ERROR_LOG_TEXT))); - assertThat(step.getDescription(), not(equalTo(DESCRIPTION_ERROR_LOG_TEXT))); } @Test @@ -182,6 +189,8 @@ public void verify_failed_step_description_step_reporter() { FinishTestItemRQ step = finishRqs.get(0); assertThat(step.getDescription(), equalTo(ERROR_LOG_TEXT)); FinishTestItemRQ test = finishRqs.get(1); - assertThat(test.getDescription(), equalTo(DESCRIPTION_ERROR_LOG_TEXT)); + assertThat(test.getDescription(), + allOf(notNullValue(), startsWith(SCENARIO_CODE_REFERENCES_WITH_ERROR.getKey()), endsWith(SCENARIO_CODE_REFERENCES_WITH_ERROR.getValue())) + ); } } From 822964fc0303605d0f7a9ac70b11f6dd146fd52b Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Wed, 20 Nov 2024 10:42:15 +0300 Subject: [PATCH 6/9] Client version update and refactoring --- CHANGELOG.md | 5 +- build.gradle | 4 +- .../cucumber/AbstractReporter.java | 126 ++++++++++-------- .../reportportal/cucumber/FailedTest.java | 44 +++--- 4 files changed, 90 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc077ea..1712d0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,11 @@ # Changelog ## [Unreleased] +### Added +- Common Stack Trace frames skip in description and logs, by @HardNorth +- Reporting of Last Error Log in Item description, by @HardNorth and @ArtemOAS ### Changed -- Client version updated on [5.2.14](https://github.com/reportportal/client-java/releases/tag/5.2.14), by @HardNorth +- Client version updated on [5.2.21](https://github.com/reportportal/client-java/releases/tag/5.2.21), by @HardNorth ## [5.2.2] ### Changed diff --git a/build.gradle b/build.gradle index d4a43c3..b830bbd 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ repositories { } dependencies { - api 'com.epam.reportportal:client-java:5.2.14' + api 'com.epam.reportportal:client-java:5.2.21' api "io.cucumber:cucumber-java:${project.cucumber_version}" implementation 'org.slf4j:slf4j-api:2.0.7' @@ -58,7 +58,7 @@ dependencies { testImplementation "org.junit.jupiter:junit-jupiter-api:${project.junit_version}" testImplementation "org.junit.jupiter:junit-jupiter-params:${project.junit_version}" testImplementation "org.junit.jupiter:junit-jupiter-engine:${project.junit_version}" - testImplementation 'org.apache.commons:commons-io:1.3.2' + testImplementation 'commons-io:commons-io:2.16.1' } test { diff --git a/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java b/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java index 8369dc1..b5bbc6f 100644 --- a/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java +++ b/src/main/java/com/epam/reportportal/cucumber/AbstractReporter.java @@ -27,8 +27,8 @@ import com.epam.reportportal.service.tree.TestItemTree; import com.epam.reportportal.utils.*; import com.epam.reportportal.utils.files.ByteSource; +import com.epam.reportportal.utils.formatting.MarkdownUtils; import com.epam.reportportal.utils.http.ContentType; -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; @@ -67,11 +67,11 @@ import static com.epam.reportportal.cucumber.Utils.*; import static com.epam.reportportal.cucumber.util.ItemTreeUtils.createKey; import static com.epam.reportportal.cucumber.util.ItemTreeUtils.retrieveLeaf; +import static com.epam.reportportal.utils.formatting.ExceptionUtils.getStackTrace; import static java.lang.String.format; import static java.util.Optional.of; import static java.util.Optional.ofNullable; import static org.apache.commons.lang3.StringUtils.isNotBlank; -import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace; /** * Abstract Cucumber 4.x formatter for Report Portal @@ -92,7 +92,6 @@ public abstract class AbstractReporter implements ConcurrentEventListener { private static final String HOOK_ = "Hook: "; private static final String DOCSTRING_DECORATOR = "\n\"\"\"\n"; private static final String ERROR_FORMAT = "Error:\n%s"; - private static final String DESCRIPTION_ERROR_FORMAT = "%s\n" + ERROR_FORMAT; public static final TestItemTree ITEM_TREE = new TestItemTree(); private static volatile ReportPortal REPORT_PORTAL = ReportPortal.builder().build(); @@ -115,11 +114,11 @@ public abstract class AbstractReporter implements ConcurrentEventListener { /** * This map uses to record the description of the scenario and the step to append the error to the description. */ - private final Map descriptionsMap = new ConcurrentHashMap<>(); + private final Map, String> descriptionsMap = new ConcurrentHashMap<>(); /** * This map uses to record errors to append to the description. */ - private final Map errorMap = new ConcurrentHashMap<>(); + private final Map, Throwable> errorMap = new ConcurrentHashMap<>(); public static ReportPortal getReportPortal() { return REPORT_PORTAL; @@ -175,7 +174,8 @@ protected TestCaseIdEntry getTestCaseId(@Nonnull TestStep testStep, @Nullable St if (definitionMatch != null) { try { Method method = retrieveMethod(definitionMatch); - return TestCaseIdUtils.getTestCaseId(method.getAnnotation(TestCaseId.class), + return TestCaseIdUtils.getTestCaseId( + method.getAnnotation(TestCaseId.class), method, codeRef, (List) ARGUMENTS_TRANSFORM.apply(arguments) @@ -248,14 +248,20 @@ private void addToTree(RunningContext.FeatureContext featureContext, RunningCont * @param scenarioContext current scenario context */ protected void beforeScenario(RunningContext.FeatureContext featureContext, RunningContext.ScenarioContext scenarioContext) { - String scenarioName = Utils.buildName(scenarioContext.getKeyword(), + String scenarioName = Utils.buildName( + scenarioContext.getKeyword(), AbstractReporter.COLON_INFIX, scenarioContext.getTestCase().getName() ); - StartTestItemRQ startTestItemRQ = buildStartScenarioRequest(scenarioContext.getTestCase(), scenarioName, featureContext.getUri(), scenarioContext.getLine()); + StartTestItemRQ startTestItemRQ = buildStartScenarioRequest( + scenarioContext.getTestCase(), + scenarioName, + featureContext.getUri(), + scenarioContext.getLine() + ); Maybe id = startScenario(featureContext.getFeatureId(), startTestItemRQ); scenarioContext.setId(id); - id.subscribe(scenarioId -> descriptionsMap.put(scenarioId, ofNullable(startTestItemRQ.getDescription()).orElse(StringUtils.EMPTY))); + descriptionsMap.put(id, ofNullable(startTestItemRQ.getDescription()).orElse(StringUtils.EMPTY)); if (launch.get().getParameters().isCallbackReportingEnabled()) { addToTree(featureContext, scenarioContext); } @@ -273,9 +279,7 @@ protected ItemStatus mapItemStatus(@Nullable Result.Type status) { return null; } else { if (STATUS_MAPPING.get(status) == null) { - LOGGER.error(String.format("Unable to find direct mapping between Cucumber and ReportPortal for TestItem with status: '%s'.", - status - )); + LOGGER.error("Unable to find direct mapping between Cucumber and ReportPortal for TestItem with status: '{}'.", status); return ItemStatus.SKIPPED; } return STATUS_MAPPING.get(status); @@ -292,34 +296,35 @@ protected ItemStatus mapItemStatus(@Nullable Result.Type status) { */ @Nonnull @SuppressWarnings("unused") - protected Maybe buildFinishTestItemRequest(@Nonnull Maybe itemId, @Nullable Date finishTime, - @Nullable ItemStatus status) { - return itemId.map(id -> { - FinishTestItemRQ rq = new FinishTestItemRQ(); - if (status == ItemStatus.FAILED) { - Optional currentDescription = Optional.ofNullable(descriptionsMap.get(itemId.blockingGet())); - Optional currentError = Optional.ofNullable(errorMap.get(itemId.blockingGet())); - currentDescription.flatMap(description -> currentError - .map(errorMessage -> resolveDescriptionErrorMessage(description, errorMessage))) - .ifPresent(rq::setDescription); - } - ofNullable(status).ifPresent(s -> rq.setStatus(s.name())); - rq.setEndTime(finishTime); - return rq; - }); + protected FinishTestItemRQ buildFinishTestItemRequest(@Nonnull Maybe itemId, @Nullable Date finishTime, + @Nullable ItemStatus status) { + FinishTestItemRQ rq = new FinishTestItemRQ(); + if (status == ItemStatus.FAILED) { + Optional currentDescription = Optional.ofNullable(descriptionsMap.remove(itemId)); + Optional currentError = Optional.ofNullable(errorMap.remove(itemId)); + currentDescription.flatMap(description -> currentError.map(errorMessage -> resolveDescriptionErrorMessage( + description, + errorMessage + ))).ifPresent(rq::setDescription); + } + ofNullable(status).ifPresent(s -> rq.setStatus(s.name())); + rq.setEndTime(finishTime); + return rq; } /** * Resolve description + * * @param currentDescription Current description - * @param error Error message + * @param error Error message * @return Description with error */ private String resolveDescriptionErrorMessage(String currentDescription, Throwable error) { + String errorStr = format(ERROR_FORMAT, getStackTrace(error, new Throwable())); return Optional.ofNullable(currentDescription) .filter(StringUtils::isNotBlank) - .map(description -> format(DESCRIPTION_ERROR_FORMAT, currentDescription, error)) - .orElse(format(ERROR_FORMAT, error)); + .map(description -> MarkdownUtils.asTwoParts(currentDescription, errorStr)) + .orElse(errorStr); } /** @@ -336,9 +341,9 @@ protected Date finishTestItem(Maybe itemId, Result.Type status) { } Date endTime = Calendar.getInstance().getTime(); - Maybe rqMaybe = buildFinishTestItemRequest(itemId, endTime, mapItemStatus(status)); + FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, endTime, mapItemStatus(status)); //noinspection ReactiveStreamsUnusedPublisher - rqMaybe.subscribe(rq -> launch.get().finishTestItem(itemId, rq)); + launch.get().finishTestItem(itemId, rq); return endTime; } @@ -367,8 +372,7 @@ protected void afterScenario(TestCaseFinished event) { String featureUri = context.getFeatureUri(); currentScenarioContextMap.remove(Pair.of(context.getLine(), featureUri)); if (mapItemStatus(event.result.getStatus()) == ItemStatus.FAILED) { - Optional.ofNullable(event.result.getError()) - .ifPresent(error -> context.getId().subscribe(id -> errorMap.put(id, error))); + Optional.ofNullable(event.result.getError()).ifPresent(error -> errorMap.put(context.getId(), error)); } Date endTime = finishTestItem(context.getId(), event.result.getStatus()); featureEndTime.put(featureUri, endTime); @@ -477,7 +481,7 @@ protected void beforeStep(TestStep testStep) { String stepText = step.getText(); context.setCurrentText(stepText); if (rq.isHasStats()) { - stepId.subscribe(id -> descriptionsMap.put(id, ofNullable(rq.getDescription()).orElse(StringUtils.EMPTY))); + descriptionsMap.put(stepId, ofNullable(rq.getDescription()).orElse(StringUtils.EMPTY)); } if (launch.get().getParameters().isCallbackReportingEnabled()) { addToTree(context, stepText, stepId); @@ -492,9 +496,8 @@ protected void beforeStep(TestStep testStep) { protected void afterStep(Result result) { reportResult(result, null); RunningContext.ScenarioContext context = getCurrentScenarioContext(); - if (mapItemStatus(result.getStatus()) == ItemStatus.FAILED){ - Optional.ofNullable(result.getError()) - .ifPresent(error -> context.getCurrentStepId().subscribe(id -> errorMap.put(id, error))); + if (mapItemStatus(result.getStatus()) == ItemStatus.FAILED) { + Optional.ofNullable(result.getError()).ifPresent(error -> errorMap.put(context.getCurrentStepId(), error)); } finishTestItem(context.getCurrentStepId(), result.getStatus()); context.setCurrentStepId(null); @@ -518,8 +521,8 @@ protected StartTestItemRQ buildStartHookRequest(HookType hookType) { /** * Start before/after-hook item on Report Portal * - * @param parentId parent item id - * @param rq hook start request + * @param parentId parent item id + * @param rq hook start request * @return hook item id */ @Nonnull @@ -598,7 +601,7 @@ protected void reportResult(Result result, String message) { if (errorMessage != null) { sendLog(errorMessage, level); } else if (result.getError() != null) { - sendLog(getStackTrace(result.getError()), level); + sendLog(getStackTrace(result.getError(), new Throwable()), level); } } @@ -623,7 +626,8 @@ protected void embedding(@Nullable String name, String mimeType, byte[] data) { String type = ofNullable(mimeType).filter(ContentType::isValidType).orElseGet(() -> getDataType(data, name)); String attachmentName = ofNullable(name).filter(m -> !m.isEmpty()) .orElseGet(() -> ofNullable(type).map(t -> t.substring(0, t.indexOf("/"))).orElse("")); - ReportPortal.emitLog(new ReportPortalMessage(ByteSource.wrap(data), type, attachmentName), + ReportPortal.emitLog( + new ReportPortalMessage(ByteSource.wrap(data), type, attachmentName), "UNKNOWN", Calendar.getInstance().getTime() ); @@ -667,9 +671,9 @@ protected void finishFeature(Maybe itemId, Date dateTime) { return; } Date endTime = ofNullable(dateTime).orElse(Calendar.getInstance().getTime()); - Maybe rqMaybe = buildFinishTestItemRequest(itemId, endTime, null); + FinishTestItemRQ rq = buildFinishTestItemRequest(itemId, endTime, null); //noinspection ReactiveStreamsUnusedPublisher - rqMaybe.subscribe(rq -> launch.get().finishTestItem(itemId, rq)); + launch.get().finishTestItem(itemId, rq); } private void removeFromTree(RunningContext.FeatureContext featureContext) { @@ -793,14 +797,16 @@ protected void handleStartOfTestCase(TestCaseStarted event) { TestCase testCase = event.testCase; RunningContext.FeatureContext newFeatureContext = new RunningContext.FeatureContext(testCase); String featureUri = newFeatureContext.getUri(); - RunningContext.FeatureContext featureContext = currentFeatureContextMap.computeIfAbsent(featureUri, u -> { - getRootItemId(); // trigger root item creation - newFeatureContext.setFeatureId(startFeature(buildStartFeatureRequest(newFeatureContext.getFeature(), featureUri))); - if (launch.get().getParameters().isCallbackReportingEnabled()) { - addToTree(newFeatureContext); - } - return newFeatureContext; - }); + RunningContext.FeatureContext featureContext = currentFeatureContextMap.computeIfAbsent( + featureUri, u -> { + getRootItemId(); // trigger root item creation + newFeatureContext.setFeatureId(startFeature(buildStartFeatureRequest(newFeatureContext.getFeature(), featureUri))); + if (launch.get().getParameters().isCallbackReportingEnabled()) { + addToTree(newFeatureContext); + } + return newFeatureContext; + } + ); if (!featureContext.getUri().equals(testCase.getUri())) { throw new IllegalStateException("Scenario URI does not match Feature URI."); @@ -809,10 +815,12 @@ protected void handleStartOfTestCase(TestCaseStarted event) { RunningContext.ScenarioContext newScenarioContext = featureContext.getScenarioContext(testCase); Pair scenarioLineFeatureURI = Pair.of(newScenarioContext.getLine(), featureContext.getUri()); - RunningContext.ScenarioContext scenarioContext = currentScenarioContextMap.computeIfAbsent(scenarioLineFeatureURI, k -> { - currentScenarioContext.set(newScenarioContext); - return newScenarioContext; - }); + RunningContext.ScenarioContext scenarioContext = currentScenarioContextMap.computeIfAbsent( + scenarioLineFeatureURI, k -> { + currentScenarioContext.set(newScenarioContext); + return newScenarioContext; + } + ); beforeScenario(featureContext, scenarioContext); } @@ -840,14 +848,16 @@ protected void handleTestStepFinished(TestStepFinished event) { } protected void addToTree(RunningContext.ScenarioContext scenarioContext, String text, Maybe stepId) { - retrieveLeaf(scenarioContext.getFeatureUri(), + retrieveLeaf( + scenarioContext.getFeatureUri(), scenarioContext.getLine(), ITEM_TREE ).ifPresent(scenarioLeaf -> scenarioLeaf.getChildItems().put(createKey(text), TestItemTree.createTestItemLeaf(stepId))); } protected void removeFromTree(RunningContext.ScenarioContext scenarioContext, String text) { - retrieveLeaf(scenarioContext.getFeatureUri(), + retrieveLeaf( + scenarioContext.getFeatureUri(), scenarioContext.getLine(), ITEM_TREE ).ifPresent(scenarioLeaf -> scenarioLeaf.getChildItems().remove(createKey(text))); diff --git a/src/test/java/com/epam/reportportal/cucumber/FailedTest.java b/src/test/java/com/epam/reportportal/cucumber/FailedTest.java index 5c55032..342add1 100644 --- a/src/test/java/com/epam/reportportal/cucumber/FailedTest.java +++ b/src/test/java/com/epam/reportportal/cucumber/FailedTest.java @@ -25,6 +25,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.formatting.MarkdownUtils; import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; import io.cucumber.testng.AbstractTestNGCucumberTests; @@ -42,41 +43,32 @@ import static com.epam.reportportal.cucumber.integration.util.TestUtils.filterLogs; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.endsWith; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.Matchers.*; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.*; -/** - * @author Ihar Kahadouski - */ public class FailedTest { - private static final String EXPECTED_ERROR = "java.lang.IllegalStateException: " + FailedSteps.ERROR_MESSAGE; - private static final String ERROR_LOG_TEXT = "Error:\n" + EXPECTED_ERROR; - private static final String DESCRIPTION_ERROR_LOG_TEXT = - "file:src/test/resources/features/FailedScenario.feature\n" - + ERROR_LOG_TEXT; + private static final String EXPECTED_STACK_TRACE = EXPECTED_ERROR + + "\n\tat com.epam.reportportal.cucumber.integration.feature.FailedSteps.i_have_a_failed_step(FailedSteps.java:31)" + + "\n\tat ✽.I have a failed step(file:src/test/resources/features/FailedScenario.feature:4)\n"; + private static final String ERROR_LOG_TEXT = "Error:\n" + EXPECTED_STACK_TRACE; - private static final Pair SCENARIO_CODE_REFERENCES_WITH_ERROR = Pair.of("file:", - "src/test/resources/features/FailedScenario.feature\n" + ERROR_LOG_TEXT + private static final String SCENARIO_CODE_REFERENCES_WITH_ERROR = MarkdownUtils.asTwoParts("file:src/test/resources/features/FailedScenario.feature", + ERROR_LOG_TEXT ); @CucumberOptions(features = "src/test/resources/features/FailedScenario.feature", glue = { "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", "com.epam.reportportal.cucumber.integration.TestScenarioReporter" }) - public static class FailedScenarioReporter extends AbstractTestNGCucumberTests { + public static class FailedScenarioReporterTest extends AbstractTestNGCucumberTests { } @CucumberOptions(features = "src/test/resources/features/FailedScenario.feature", glue = { "com.epam.reportportal.cucumber.integration.feature" }, plugin = { "pretty", "com.epam.reportportal.cucumber.integration.TestStepReporter" }) - public static class FailedStepReporter extends AbstractTestNGCucumberTests { + public static class FailedStepReporterTest extends AbstractTestNGCucumberTests { } @@ -104,7 +96,7 @@ public void initLaunch() { @Test @SuppressWarnings("unchecked") public void verify_failed_step_reporting_scenario_reporter() { - TestUtils.runTests(FailedScenarioReporter.class); + TestUtils.runTests(FailedScenarioReporterTest.class); verify(client).startTestItem(any()); verify(client).startTestItem(same(suiteId), any()); @@ -130,7 +122,7 @@ public void verify_failed_step_reporting_scenario_reporter() { @Test @SuppressWarnings("unchecked") public void verify_failed_step_reporting_step_reporter() { - TestUtils.runTests(FailedStepReporter.class); + TestUtils.runTests(FailedStepReporterTest.class); verify(client).startTestItem(any()); verify(client).startTestItem(same(suiteId), any()); @@ -151,9 +143,8 @@ public void verify_failed_step_reporting_step_reporter() { } @Test - @SuppressWarnings("unchecked") public void verify_failed_nested_step_description_scenario_reporter() { - TestUtils.runTests(FailedScenarioReporter.class); + TestUtils.runTests(FailedScenarioReporterTest.class); verify(client).startTestItem(any()); verify(client).startTestItem(same(suiteId), any()); @@ -172,9 +163,8 @@ public void verify_failed_nested_step_description_scenario_reporter() { } @Test - @SuppressWarnings("unchecked") public void verify_failed_step_description_step_reporter() { - TestUtils.runTests(FailedStepReporter.class); + TestUtils.runTests(FailedStepReporterTest.class); verify(client).startTestItem(any()); verify(client).startTestItem(same(suiteId), any()); @@ -189,8 +179,6 @@ public void verify_failed_step_description_step_reporter() { FinishTestItemRQ step = finishRqs.get(0); assertThat(step.getDescription(), equalTo(ERROR_LOG_TEXT)); FinishTestItemRQ test = finishRqs.get(1); - assertThat(test.getDescription(), - allOf(notNullValue(), startsWith(SCENARIO_CODE_REFERENCES_WITH_ERROR.getKey()), endsWith(SCENARIO_CODE_REFERENCES_WITH_ERROR.getValue())) - ); + assertThat(test.getDescription(), equalTo(SCENARIO_CODE_REFERENCES_WITH_ERROR)); } } From 74cdb85b270ae339b7924d1c83540e893203b4fc Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Wed, 20 Nov 2024 10:43:48 +0300 Subject: [PATCH 7/9] Logger version update --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b830bbd..49646c6 100644 --- a/build.gradle +++ b/build.gradle @@ -49,7 +49,7 @@ 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.12' + testImplementation 'ch.qos.logback:logback-classic:1.4.12' testImplementation "io.cucumber:cucumber-testng:${project.cucumber_version}" testImplementation 'com.epam.reportportal:logger-java-logback:5.2.2' testImplementation ("org.junit.platform:junit-platform-runner:${project.junit_runner_version}") { From ba99c57b53518360e35e68bc6d64bf6193efb69b Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Wed, 20 Nov 2024 10:48:29 +0300 Subject: [PATCH 8/9] Revert "Logger version update" This reverts commit 74cdb85b270ae339b7924d1c83540e893203b4fc. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 49646c6..b830bbd 100644 --- a/build.gradle +++ b/build.gradle @@ -49,7 +49,7 @@ 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.4.12' + 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.2.2' testImplementation ("org.junit.platform:junit-platform-runner:${project.junit_runner_version}") { From 83eb37cb9bdc5bbdbcb0cd2ef91585c750db80e3 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Wed, 20 Nov 2024 10:49:27 +0300 Subject: [PATCH 9/9] Logger version update --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b830bbd..a8bbd25 100644 --- a/build.gradle +++ b/build.gradle @@ -49,7 +49,7 @@ 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.12' + testImplementation 'ch.qos.logback:logback-classic:1.3.14' testImplementation "io.cucumber:cucumber-testng:${project.cucumber_version}" testImplementation 'com.epam.reportportal:logger-java-logback:5.2.2' testImplementation ("org.junit.platform:junit-platform-runner:${project.junit_runner_version}") {