From 060d83b54f9fce71ad85413b24aa563101305f03 Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 6 Aug 2026 19:45:32 +0300 Subject: [PATCH 1/2] Issue-143. feat: add retry support for Cucumber scenarios --- java-reporter-core/pom.xml | 12 ++-- .../core/constants/CommonConstants.java | 2 +- java-reporter-cucumber/pom.xml | 4 +- .../CucumberTestResultConstructor.java | 2 +- .../cucumber/extractor/TestDataExtractor.java | 55 ++++++++++++++++- .../cucumber/listener/CucumberListener.java | 28 +++++++++ .../listener/CucumberTestRegistry.java | 61 +++++++++++++++++++ .../CucumberTestResultConstructorTest.java | 20 +++--- .../extractor/TestDataExtractorTest.java | 51 ++++++++++++++++ .../listener/CucumberListenerTest.java | 3 + java-reporter-junit/pom.xml | 4 +- java-reporter-karate/pom.xml | 4 +- java-reporter-testng/pom.xml | 4 +- .../TestNgTestResultConstructor.java | 3 +- testomat-allure-adapter/pom.xml | 4 +- .../resolver/JUnitDisplayNameResolver.java | 9 +-- 16 files changed, 234 insertions(+), 32 deletions(-) create mode 100644 java-reporter-cucumber/src/main/java/io/testomat/cucumber/listener/CucumberTestRegistry.java diff --git a/java-reporter-core/pom.xml b/java-reporter-core/pom.xml index b21553b7..dce2e9b4 100644 --- a/java-reporter-core/pom.xml +++ b/java-reporter-core/pom.xml @@ -7,7 +7,7 @@ io.testomat java-reporter-core - 0.17.0 + 0.18.0 jar Testomat.io Reporter Core @@ -33,8 +33,8 @@ - 17 - 17 + 11 + 11 UTF-8 UTF-8 @@ -149,9 +149,9 @@ 1.14.1 - 17 - 17 - 17 + 11 + 11 + 11 diff --git a/java-reporter-core/src/main/java/io/testomat/core/constants/CommonConstants.java b/java-reporter-core/src/main/java/io/testomat/core/constants/CommonConstants.java index ea32a7a9..d5938400 100644 --- a/java-reporter-core/src/main/java/io/testomat/core/constants/CommonConstants.java +++ b/java-reporter-core/src/main/java/io/testomat/core/constants/CommonConstants.java @@ -1,7 +1,7 @@ package io.testomat.core.constants; public class CommonConstants { - public static final String REPORTER_VERSION = "0.17.0"; + public static final String REPORTER_VERSION = "0.18.0"; public static final String TESTS_STRING = "tests"; public static final String API_KEY_STRING = "api_key"; diff --git a/java-reporter-cucumber/pom.xml b/java-reporter-cucumber/pom.xml index 5f63e3c3..b4a58340 100644 --- a/java-reporter-cucumber/pom.xml +++ b/java-reporter-cucumber/pom.xml @@ -6,7 +6,7 @@ io.testomat java-reporter-cucumber - 0.8.3 + 0.9.0 jar Testomat.io Java Reporter Cucumber @@ -51,7 +51,7 @@ io.testomat java-reporter-core - 0.17.0 + 0.18.0 org.slf4j diff --git a/java-reporter-cucumber/src/main/java/io/testomat/cucumber/constructor/CucumberTestResultConstructor.java b/java-reporter-cucumber/src/main/java/io/testomat/cucumber/constructor/CucumberTestResultConstructor.java index 975e6aa3..a4909e9c 100644 --- a/java-reporter-cucumber/src/main/java/io/testomat/cucumber/constructor/CucumberTestResultConstructor.java +++ b/java-reporter-cucumber/src/main/java/io/testomat/cucumber/constructor/CucumberTestResultConstructor.java @@ -57,7 +57,7 @@ public TestResult constructTestRunResult(TestCaseFinished event) { .withTestId(testDataExtractor.extractTestId(event)) .withFile(fileName) .withTitle(testDataExtractor.extractTitle(event)) - .withRid(event.getTestCase().getId().toString()) + .withRid(testDataExtractor.generateRid(event)) .withMessage(exceptionDetails.getMessage()) .withStack(exceptionDetails.getStack()); diff --git a/java-reporter-cucumber/src/main/java/io/testomat/cucumber/extractor/TestDataExtractor.java b/java-reporter-cucumber/src/main/java/io/testomat/cucumber/extractor/TestDataExtractor.java index 686be36e..3259a152 100644 --- a/java-reporter-cucumber/src/main/java/io/testomat/cucumber/extractor/TestDataExtractor.java +++ b/java-reporter-cucumber/src/main/java/io/testomat/cucumber/extractor/TestDataExtractor.java @@ -7,6 +7,7 @@ import io.cucumber.plugin.event.PickleStepTestStep; import io.cucumber.plugin.event.Result; import io.cucumber.plugin.event.TestCase; +import io.cucumber.plugin.event.TestCaseEvent; import io.cucumber.plugin.event.TestCaseFinished; import io.cucumber.plugin.event.TestStep; import io.testomat.core.model.ExceptionDetails; @@ -14,6 +15,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -54,6 +56,52 @@ public Map createExample(TestCaseFinished event) { return params; } + /** + * Generates a unique run ID for a Cucumber test case. + * Combines the feature URI, scenario name and parameter values extracted from step text. + * Simple values are appended directly, complex values are hashed. + * + * @param event the Cucumber test case finished event + * @return the generated run ID + */ + public String generateRid(TestCaseFinished event) { + TestCase testCase = event.getTestCase(); + StringBuilder ridBuilder = new StringBuilder(); + ridBuilder.append(testCase.getUri()) + .append(".") + .append(testCase.getName()); + + Map params = new LinkedHashMap<>(); + List testSteps = testCase.getTestSteps(); + if (testSteps != null) { + for (TestStep testStep : testSteps) { + if (testStep instanceof PickleStepTestStep) { + String stepText = ((PickleStepTestStep) testStep).getStepText(); + params.putAll(extractValuesFromStepText(stepText)); + } + } + } + + if (params.isEmpty()) { + return ridBuilder.toString(); + } + + for (Map.Entry entry : params.entrySet()) { + Object param = entry.getValue(); + String paramString = param != null ? param.toString() : "null"; + String paramName = entry.getKey(); + + if (paramString.length() <= 20 && paramString.matches("[a-zA-Z0-9._-]+")) { + ridBuilder.append("-").append(paramName).append("_").append(paramString); + } else { + int hash = Math.abs(paramString.hashCode()); + ridBuilder.append("-").append(paramName).append("_h").append(hash); + } + } + + return ridBuilder.toString(); + } + /** * Extracts exception details from test execution result. * @@ -74,7 +122,10 @@ public ExceptionDetails extractExceptionDetails(TestCaseFinished event) { * @param event the Cucumber test case finished event * @return test ID if found, null otherwise */ - public String extractTestId(TestCaseFinished event) { + public String extractTestId(TestCaseEvent event) { + if (event == null) { + return null; + } TestCase testCase = event.getTestCase(); if (testCase == null || testCase.getTags() == null) { return null; @@ -138,7 +189,7 @@ public String getNormalizedStatus(TestCaseFinished event) { } private Map extractValuesFromStepText(String stepText) { - Map values = new HashMap<>(); + Map values = new LinkedHashMap<>(); Pattern quotedPattern = Pattern.compile(QUOTED_PATTERN); Matcher matcher = quotedPattern.matcher(stepText); diff --git a/java-reporter-cucumber/src/main/java/io/testomat/cucumber/listener/CucumberListener.java b/java-reporter-cucumber/src/main/java/io/testomat/cucumber/listener/CucumberListener.java index e7d441ca..f7ca08a7 100644 --- a/java-reporter-cucumber/src/main/java/io/testomat/cucumber/listener/CucumberListener.java +++ b/java-reporter-cucumber/src/main/java/io/testomat/cucumber/listener/CucumberListener.java @@ -1,9 +1,13 @@ package io.testomat.cucumber.listener; +import static io.testomat.core.constants.CommonConstants.FAILED; +import static io.testomat.core.constants.CommonConstants.PASSED; + import io.cucumber.plugin.EventListener; import io.cucumber.plugin.Plugin; import io.cucumber.plugin.event.EventPublisher; import io.cucumber.plugin.event.TestCaseFinished; +import io.cucumber.plugin.event.TestCaseStarted; import io.cucumber.plugin.event.TestRunFinished; import io.cucumber.plugin.event.TestRunStarted; import io.testomat.core.exception.ReportTestResultException; @@ -67,6 +71,8 @@ public void setEventPublisher(EventPublisher eventPublisher) { TestRunStarted.class, this::handleTestRunStarted); eventPublisher.registerHandlerFor( TestRunFinished.class, this::handleTestRunFinished); + eventPublisher.registerHandlerFor( + TestCaseStarted.class, this::handleTestCaseStarted); eventPublisher.registerHandlerFor( TestCaseFinished.class, this::handleTestCaseFinished); } @@ -83,6 +89,19 @@ void handleTestRunFinished(TestRunFinished event) { onTestRunFinishedHookAfterExecution(event); } + void handleTestCaseStarted(TestCaseStarted event) { + String key = event.getTestCase().getUri() + + "." + + event.getTestCase().getName(); + + if (CucumberTestRegistry.isProcessed(key) + && !CucumberTestRegistry.containsTestId(dataExtractor.extractTestId(event))) { + return; + } + + CucumberTestRegistry.add(key, dataExtractor.extractTestId(event)); + } + void handleTestCaseFinished(TestCaseFinished event) { if (!runManager.isActive()) { return; @@ -95,6 +114,15 @@ void handleTestCaseFinished(TestCaseFinished event) { try { onTestCaseFinishedHookBeforeExecution(event); TestResult result = resultConstructor.constructTestRunResult(event); + + if (CucumberTestRegistry.containsTestId(result.getTestId())) { + result.setOverwrite(false); + + if (!PASSED.equals(result.getStatus())) { + result.setStatus(FAILED); + } + } + runManager.reportTest(result); onTestCaseFinishedHookAfterExecution(event); } catch (Exception e) { diff --git a/java-reporter-cucumber/src/main/java/io/testomat/cucumber/listener/CucumberTestRegistry.java b/java-reporter-cucumber/src/main/java/io/testomat/cucumber/listener/CucumberTestRegistry.java new file mode 100644 index 00000000..278d5e6c --- /dev/null +++ b/java-reporter-cucumber/src/main/java/io/testomat/cucumber/listener/CucumberTestRegistry.java @@ -0,0 +1,61 @@ +package io.testomat.cucumber.listener; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Cucumber may recreate the listener instance for each retry within the same JVM + * so the processed keys and test IDs are kept here instead of in the listener. + */ +public final class CucumberTestRegistry { + + private static final List processedTests = + Collections.synchronizedList(new ArrayList<>()); + private static final Set testIds = + Collections.synchronizedSet(new HashSet<>()); + + private CucumberTestRegistry() { + } + + /** + * Checks whether the composite test key was already processed in this JVM. + * + * @param key the composite test key + * @return true if the key was already processed + */ + public static boolean isProcessed(String key) { + return processedTests.contains(key); + } + + /** + * Checks whether the test ID was already seen in this JVM. + * + * @param testId the test ID + * @return true if the test ID was already seen + */ + public static boolean containsTestId(String testId) { + return testIds.contains(testId); + } + + /** + * Records the composite test key and test ID. + * + * @param key the composite test key + * @param testId the test ID + */ + public static void add(String key, String testId) { + processedTests.add(key); + testIds.add(testId); + } + + /** + * Clears all tracked state. Used by tests to isolate scenarios. + */ + static void reset() { + processedTests.clear(); + testIds.clear(); + } +} diff --git a/java-reporter-cucumber/src/test/java/io/testomat/cucumber/constructor/CucumberTestResultConstructorTest.java b/java-reporter-cucumber/src/test/java/io/testomat/cucumber/constructor/CucumberTestResultConstructorTest.java index 923028e3..2166559a 100644 --- a/java-reporter-cucumber/src/test/java/io/testomat/cucumber/constructor/CucumberTestResultConstructorTest.java +++ b/java-reporter-cucumber/src/test/java/io/testomat/cucumber/constructor/CucumberTestResultConstructorTest.java @@ -12,6 +12,7 @@ import org.mockito.MockitoAnnotations; import java.net.URI; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -58,12 +59,14 @@ void shouldConstructTestRunResultWithAllFields() { when(testCaseFinished.getTestCase()).thenReturn(testCase); when(testCase.getUri()).thenReturn(testUri); - when(testCase.getId()).thenReturn(testCaseId); - + when(testCase.getName()).thenReturn("Test Scenario"); + when(testCase.getTestSteps()).thenReturn(Collections.emptyList()); + when(testDataExtractor.extractExceptionDetails(testCaseFinished)).thenReturn(exceptionDetails); when(testDataExtractor.getNormalizedStatus(testCaseFinished)).thenReturn("PASSED"); when(testDataExtractor.createExample(testCaseFinished)).thenReturn(example); when(testDataExtractor.extractTestId(testCaseFinished)).thenReturn("@T12345678"); + when(testDataExtractor.generateRid(testCaseFinished)).thenReturn("file:///test/path/TestFeature.feature.Test Scenario"); when(testDataExtractor.extractFileName(testCaseFinished)).thenReturn("file:///test/path/TestFeature.feature"); when(testDataExtractor.extractTitle(testCaseFinished)).thenReturn("Test Title"); @@ -78,7 +81,7 @@ void shouldConstructTestRunResultWithAllFields() { assertEquals("@T12345678", result.getTestId()); assertEquals("file:///test/path/TestFeature.feature", result.getFile()); assertEquals("Test Title", result.getTitle()); - assertEquals(testCaseId.toString(), result.getRid()); + assertEquals("file:///test/path/TestFeature.feature.Test Scenario", result.getRid()); assertEquals("Test error", result.getMessage()); assertEquals("Stack trace", result.getStack()); } @@ -93,12 +96,14 @@ void shouldConstructTestRunResultWithEmptyExceptionDetails() { when(testCaseFinished.getTestCase()).thenReturn(testCase); when(testCase.getUri()).thenReturn(testUri); - when(testCase.getId()).thenReturn(testCaseId); - + when(testCase.getName()).thenReturn("Test Scenario"); + when(testCase.getTestSteps()).thenReturn(Collections.emptyList()); + when(testDataExtractor.extractExceptionDetails(testCaseFinished)).thenReturn(emptyExceptionDetails); when(testDataExtractor.getNormalizedStatus(testCaseFinished)).thenReturn("FAILED"); when(testDataExtractor.createExample(testCaseFinished)).thenReturn(emptyExample); when(testDataExtractor.extractTestId(testCaseFinished)).thenReturn(null); + when(testDataExtractor.generateRid(testCaseFinished)).thenReturn("file:///test/path/TestFeature.feature.Test Scenario"); when(testDataExtractor.extractFileName(testCaseFinished)).thenReturn(null); when(testDataExtractor.extractTitle(testCaseFinished)).thenReturn("Unknown test"); @@ -113,7 +118,7 @@ void shouldConstructTestRunResultWithEmptyExceptionDetails() { assertNull(result.getTestId()); assertNull(result.getFile()); assertEquals("Unknown test", result.getTitle()); - assertEquals(testCaseId.toString(), result.getRid()); + assertEquals("file:///test/path/TestFeature.feature.Test Scenario", result.getRid()); assertNull(result.getMessage()); assertNull(result.getStack()); } @@ -130,7 +135,7 @@ void shouldVerifyAllExtractorMethodsAreCalled() { when(testDataExtractor.extractExceptionDetails(any())).thenReturn(ExceptionDetails.empty()); when(testDataExtractor.getNormalizedStatus(any())).thenReturn("PASSED"); when(testDataExtractor.createExample(any())).thenReturn(new HashMap<>()); - when(testDataExtractor.extractTestId(any())).thenReturn(null); + when(testDataExtractor.extractTestId(any(TestCaseFinished.class))).thenReturn(null); when(testDataExtractor.extractFileName(any())).thenReturn("file:///test.feature"); when(testDataExtractor.extractTitle(any())).thenReturn("Test"); @@ -142,6 +147,7 @@ void shouldVerifyAllExtractorMethodsAreCalled() { verify(testDataExtractor).getNormalizedStatus(testCaseFinished); verify(testDataExtractor).createExample(testCaseFinished); verify(testDataExtractor).extractTestId(testCaseFinished); + verify(testDataExtractor).generateRid(testCaseFinished); verify(testDataExtractor).extractFileName(testCaseFinished); verify(testDataExtractor).extractTitle(testCaseFinished); } diff --git a/java-reporter-cucumber/src/test/java/io/testomat/cucumber/extractor/TestDataExtractorTest.java b/java-reporter-cucumber/src/test/java/io/testomat/cucumber/extractor/TestDataExtractorTest.java index a08937fc..50da6bef 100644 --- a/java-reporter-cucumber/src/test/java/io/testomat/cucumber/extractor/TestDataExtractorTest.java +++ b/java-reporter-cucumber/src/test/java/io/testomat/cucumber/extractor/TestDataExtractorTest.java @@ -96,6 +96,57 @@ void shouldExtractValuesFromComplexStepText() { assertEquals(2L, example.get("step_value_3")); } + @Test + void shouldGenerateRidWithSimpleValues() { + // Given + URI uri = URI.create("classpath:features/login.feature"); + when(testCaseFinished.getTestCase()).thenReturn(testCase); + when(testCase.getUri()).thenReturn(uri); + when(testCase.getName()).thenReturn("Login"); + when(testCase.getTestSteps()).thenReturn(Collections.singletonList(pickleStepTestStep)); + when(pickleStepTestStep.getStepText()).thenReturn("I enter 'John' and age 25 and amount 10.5"); + + // When + String rid = extractor.generateRid(testCaseFinished); + + // Then + assertEquals("classpath:features/login.feature.Login-step_value_0_John" + + "-step_value_1_25-step_value_2_10.5", rid); + } + + @Test + void shouldGenerateRidWithHashForComplexValue() { + // Given + URI uri = URI.create("classpath:features/orders.feature"); + when(testCaseFinished.getTestCase()).thenReturn(testCase); + when(testCase.getUri()).thenReturn(uri); + when(testCase.getName()).thenReturn("Place order"); + when(testCase.getTestSteps()).thenReturn(Collections.singletonList(pickleStepTestStep)); + when(pickleStepTestStep.getStepText()).thenReturn("I place order with 'long complex order reference #123 !'"); + + // When + String rid = extractor.generateRid(testCaseFinished); + + // Then + assertTrue(rid.startsWith("classpath:features/orders.feature.Place order-step_value_0_h")); + } + + @Test + void shouldGenerateRidWithoutParameters() { + // Given + URI uri = URI.create("classpath:features/smoke.feature"); + when(testCaseFinished.getTestCase()).thenReturn(testCase); + when(testCase.getUri()).thenReturn(uri); + when(testCase.getName()).thenReturn("Health check"); + when(testCase.getTestSteps()).thenReturn(Collections.singletonList(testStep)); + + // When + String rid = extractor.generateRid(testCaseFinished); + + // Then + assertEquals("classpath:features/smoke.feature.Health check", rid); + } + @Test void shouldExtractExceptionDetailsWhenErrorExists() { // Given diff --git a/java-reporter-cucumber/src/test/java/io/testomat/cucumber/listener/CucumberListenerTest.java b/java-reporter-cucumber/src/test/java/io/testomat/cucumber/listener/CucumberListenerTest.java index a0ad0fa9..87121382 100644 --- a/java-reporter-cucumber/src/test/java/io/testomat/cucumber/listener/CucumberListenerTest.java +++ b/java-reporter-cucumber/src/test/java/io/testomat/cucumber/listener/CucumberListenerTest.java @@ -3,6 +3,7 @@ import io.cucumber.plugin.event.EventPublisher; import io.cucumber.plugin.event.TestCase; import io.cucumber.plugin.event.TestCaseFinished; +import io.cucumber.plugin.event.TestCaseStarted; import io.cucumber.plugin.event.TestRunFinished; import io.cucumber.plugin.event.TestRunStarted; import io.testomat.core.exception.ReportTestResultException; @@ -58,6 +59,7 @@ class CucumberListenerTest { @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); + CucumberTestRegistry.reset(); listener = new CucumberListener(resultConstructor, runManager, null, dataExtractor, functionsHandler); } @Test @@ -74,6 +76,7 @@ void shouldRegisterEventHandlers() { // Then verify(eventPublisher).registerHandlerFor(eq(TestRunStarted.class), any()); verify(eventPublisher).registerHandlerFor(eq(TestRunFinished.class), any()); + verify(eventPublisher).registerHandlerFor(eq(TestCaseStarted.class), any()); verify(eventPublisher).registerHandlerFor(eq(TestCaseFinished.class), any()); } diff --git a/java-reporter-junit/pom.xml b/java-reporter-junit/pom.xml index ee5366e9..e199b356 100644 --- a/java-reporter-junit/pom.xml +++ b/java-reporter-junit/pom.xml @@ -6,7 +6,7 @@ io.testomat java-reporter-junit - 0.9.3 + 0.9.4 jar Testomat.io Java Reporter JUnit @@ -51,7 +51,7 @@ io.testomat java-reporter-core - 0.17.0 + 0.18.0 org.slf4j diff --git a/java-reporter-karate/pom.xml b/java-reporter-karate/pom.xml index df5383b5..18e16bf4 100644 --- a/java-reporter-karate/pom.xml +++ b/java-reporter-karate/pom.xml @@ -6,7 +6,7 @@ io.testomat java-reporter-karate - 0.3.3 + 0.3.4 jar Testomat.io Java Reporter Karate @@ -52,7 +52,7 @@ io.testomat java-reporter-core - 0.17.0 + 0.18.0 io.karatelabs diff --git a/java-reporter-testng/pom.xml b/java-reporter-testng/pom.xml index 63245cc8..5817d74f 100644 --- a/java-reporter-testng/pom.xml +++ b/java-reporter-testng/pom.xml @@ -6,7 +6,7 @@ io.testomat java-reporter-testng - 0.8.3 + 0.8.4 jar Testomat.io Java Reporter TestNG @@ -47,7 +47,7 @@ io.testomat java-reporter-core - 0.17.0 + 0.18.0 org.slf4j diff --git a/java-reporter-testng/src/main/java/io/testomat/testng/constructor/TestNgTestResultConstructor.java b/java-reporter-testng/src/main/java/io/testomat/testng/constructor/TestNgTestResultConstructor.java index 683b50e6..066d3ff0 100644 --- a/java-reporter-testng/src/main/java/io/testomat/testng/constructor/TestNgTestResultConstructor.java +++ b/java-reporter-testng/src/main/java/io/testomat/testng/constructor/TestNgTestResultConstructor.java @@ -1,6 +1,7 @@ package io.testomat.testng.constructor; import io.testomat.core.model.ExceptionDetails; +import io.testomat.core.model.TestMetadata; import io.testomat.core.model.TestResult; import io.testomat.core.step.StepLifecycle; import io.testomat.core.step.StepStorage; @@ -59,7 +60,7 @@ private void validateWrapper(TestResultWrapper wrapper) { * Enhanced to include parameterized test data (example and RID) and test steps. */ private TestResult buildTestResult(TestResultWrapper wrapper, String message, String stack) { - var metadata = wrapper.getTestMetadata(); + TestMetadata metadata = wrapper.getTestMetadata(); // Collect steps from ThreadLocal storage List steps = StepStorage.getSteps(); diff --git a/testomat-allure-adapter/pom.xml b/testomat-allure-adapter/pom.xml index 8bd0c8ae..d0690d42 100644 --- a/testomat-allure-adapter/pom.xml +++ b/testomat-allure-adapter/pom.xml @@ -6,7 +6,7 @@ io.testomat testomat-allure-adapter - 0.1.4 + 0.1.5 jar Testomat.io Testomat Allure adapter @@ -67,7 +67,7 @@ io.testomat java-reporter-core - 0.17.0 + 0.18.0 io.qameta.allure diff --git a/testomat-allure-adapter/src/main/java/io/testomat/resolver/JUnitDisplayNameResolver.java b/testomat-allure-adapter/src/main/java/io/testomat/resolver/JUnitDisplayNameResolver.java index cc0e27d8..08ae6e9e 100644 --- a/testomat-allure-adapter/src/main/java/io/testomat/resolver/JUnitDisplayNameResolver.java +++ b/testomat-allure-adapter/src/main/java/io/testomat/resolver/JUnitDisplayNameResolver.java @@ -1,5 +1,6 @@ package io.testomat.resolver; +import java.lang.annotation.Annotation; import java.lang.reflect.Method; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,11 +18,11 @@ public class JUnitDisplayNameResolver implements TestMetadataResolver { */ @Override public String resolve(Method method) { - for (var a : method.getAnnotations()) { - if (a.annotationType().getName().equals("org.junit.jupiter.api.DisplayName")) { + for (Annotation ann : method.getAnnotations()) { + if (ann.annotationType().getName().equals("org.junit.jupiter.api.DisplayName")) { try { - Method m = a.annotationType().getMethod("value"); - String value = (String) m.invoke(a); + Method m = ann.annotationType().getMethod("value"); + String value = (String) m.invoke(ann); if (value != null && !value.isBlank()) { return value; } From 348a30fd25182e22dea6b7b9cfa9c0a75d85c890 Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 6 Aug 2026 20:41:10 +0300 Subject: [PATCH 2/2] Issue-143. add timeout-minutes --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f8d7cd1..24119a92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,7 @@ on: jobs: test: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@v4