diff --git a/allure-citrus/src/main/java/io/qameta/allure/citrus/AllureCitrus.java b/allure-citrus/src/main/java/io/qameta/allure/citrus/AllureCitrus.java index d501b3a2..8aeac02d 100644 --- a/allure-citrus/src/main/java/io/qameta/allure/citrus/AllureCitrus.java +++ b/allure-citrus/src/main/java/io/qameta/allure/citrus/AllureCitrus.java @@ -59,6 +59,7 @@ import static io.qameta.allure.util.ResultsUtils.createParameter; import static io.qameta.allure.util.ResultsUtils.createSuiteLabel; import static io.qameta.allure.util.ResultsUtils.createThreadLabel; +import static io.qameta.allure.util.ResultsUtils.createTitlePath; import static io.qameta.allure.util.ResultsUtils.getProvidedLabels; /** @@ -161,16 +162,19 @@ public void onTestActionSkipped(final TestCase testCase, final TestAction testAc private void startTestCase(final TestCase testCase) { final String uuid = createUuid(testCase); + final Optional> testClass = Optional.ofNullable(testCase.getTestClass()); final TestResult result = new TestResult() .setUuid(uuid) .setName(testCase.getName()) + .setTitlePath(testClass + .map(ResultsUtils::createTitlePathFromJavaClass) + .orElseGet(() -> createTitlePath(testCase.getName()))) .setStage(Stage.RUNNING); result.getLabels().addAll(getProvidedLabels()); - final Optional> testClass = Optional.ofNullable(testCase.getTestClass()); testClass.map(this::getLabels).ifPresent(result.getLabels()::addAll); testClass.map(this::getLinks).ifPresent(result.getLinks()::addAll); diff --git a/allure-citrus/src/test/java/io/qameta/allure/citrus/AllureCitrusTest.java b/allure-citrus/src/test/java/io/qameta/allure/citrus/AllureCitrusTest.java index bf12e299..eb4b05d2 100644 --- a/allure-citrus/src/test/java/io/qameta/allure/citrus/AllureCitrusTest.java +++ b/allure-citrus/src/test/java/io/qameta/allure/citrus/AllureCitrusTest.java @@ -61,6 +61,8 @@ void shouldSetName() { assertThat(results.getTestResults()) .extracting(TestResult::getName) .containsExactly("Simple test"); + assertThat(results.getTestResults().get(0).getTitlePath()) + .containsExactly("com", "consol", "citrus", "dsl", "design", "DefaultTestDesigner"); } @AllureFeatures.PassedTests diff --git a/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/AllureCucumber4Jvm.java b/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/AllureCucumber4Jvm.java index 967ee1a3..8f57e500 100644 --- a/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/AllureCucumber4Jvm.java +++ b/allure-cucumber4-jvm/src/main/java/io/qameta/allure/cucumber4jvm/AllureCucumber4Jvm.java @@ -71,6 +71,8 @@ import static cucumber.api.HookType.Before; import static io.qameta.allure.util.ResultsUtils.createParameter; +import static io.qameta.allure.util.ResultsUtils.createTitlePath; +import static io.qameta.allure.util.ResultsUtils.createTitlePathFromSourcePath; import static io.qameta.allure.util.ResultsUtils.getStatus; import static io.qameta.allure.util.ResultsUtils.getStatusDetails; import static io.qameta.allure.util.ResultsUtils.md5; @@ -156,11 +158,15 @@ private void handleTestCaseStarted(final TestCaseStarted event) { final String testCaseUuid = testCaseUuids .computeIfAbsent(testCase, tc -> UUID.randomUUID().toString()); + final List titlePath = createTitlePathFromSourcePath(getTestCaseUri(testCase)); + titlePath.addAll(createTitlePath(feature.getName())); + final TestResult result = new TestResult() .setUuid(testCaseUuid) .setTestCaseId(getTestCaseId(testCase)) .setHistoryId(getHistoryId(testCase)) .setFullName(fullName) + .setTitlePath(titlePath) .setName(name) .setLabels(labelBuilder.getScenarioLabels()) .setLinks(labelBuilder.getScenarioLinks()); diff --git a/allure-cucumber4-jvm/src/test/java/io/qameta/allure/cucumber4jvm/AllureCucumber4JvmTest.java b/allure-cucumber4-jvm/src/test/java/io/qameta/allure/cucumber4jvm/AllureCucumber4JvmTest.java index 85a1d093..a957cd88 100644 --- a/allure-cucumber4-jvm/src/test/java/io/qameta/allure/cucumber4jvm/AllureCucumber4JvmTest.java +++ b/allure-cucumber4-jvm/src/test/java/io/qameta/allure/cucumber4jvm/AllureCucumber4JvmTest.java @@ -77,6 +77,8 @@ void shouldSetName() { assertThat(testResults) .extracting(TestResult::getName) .containsExactlyInAnyOrder("Add a to b"); + assertThat(testResults.get(0).getTitlePath()) + .containsExactly("src", "test", "resources", "features", "simple.feature", "Simple feature"); } @AllureFeatures.PassedTests diff --git a/allure-cucumber5-jvm/src/main/java/io/qameta/allure/cucumber5jvm/AllureCucumber5Jvm.java b/allure-cucumber5-jvm/src/main/java/io/qameta/allure/cucumber5jvm/AllureCucumber5Jvm.java index e1e9debb..a0dec5f3 100644 --- a/allure-cucumber5-jvm/src/main/java/io/qameta/allure/cucumber5jvm/AllureCucumber5Jvm.java +++ b/allure-cucumber5-jvm/src/main/java/io/qameta/allure/cucumber5jvm/AllureCucumber5Jvm.java @@ -67,6 +67,8 @@ import java.util.stream.Stream; import static io.qameta.allure.util.ResultsUtils.createParameter; +import static io.qameta.allure.util.ResultsUtils.createTitlePath; +import static io.qameta.allure.util.ResultsUtils.createTitlePathFromSourcePath; import static io.qameta.allure.util.ResultsUtils.getStatus; import static io.qameta.allure.util.ResultsUtils.getStatusDetails; import static io.qameta.allure.util.ResultsUtils.md5; @@ -150,11 +152,15 @@ private void handleTestCaseStarted(final TestCaseStarted event) { final String testCaseUuid = testCase.getId().toString(); + final List titlePath = createTitlePathFromSourcePath(getTestCaseUri(testCase)); + titlePath.addAll(createTitlePath(feature.getName())); + final TestResult result = new TestResult() .setUuid(testCaseUuid) .setTestCaseId(getTestCaseId(testCase)) .setHistoryId(getHistoryId(testCase)) .setFullName(fullName) + .setTitlePath(titlePath) .setName(name) .setLabels(labelBuilder.getScenarioLabels()) .setLinks(labelBuilder.getScenarioLinks()); diff --git a/allure-cucumber5-jvm/src/test/java/io/qameta/allure/cucumber5jvm/AllureCucumber5JvmTest.java b/allure-cucumber5-jvm/src/test/java/io/qameta/allure/cucumber5jvm/AllureCucumber5JvmTest.java index 7456106a..ff4a2e24 100644 --- a/allure-cucumber5-jvm/src/test/java/io/qameta/allure/cucumber5jvm/AllureCucumber5JvmTest.java +++ b/allure-cucumber5-jvm/src/test/java/io/qameta/allure/cucumber5jvm/AllureCucumber5JvmTest.java @@ -80,6 +80,8 @@ void shouldSetName() { assertThat(testResults) .extracting(TestResult::getName) .containsExactlyInAnyOrder("Add a to b"); + assertThat(testResults.get(0).getTitlePath()) + .containsExactly("src", "test", "resources", "features", "simple.feature", "Simple feature"); } @AllureFeatures.PassedTests diff --git a/allure-cucumber6-jvm/src/main/java/io/qameta/allure/cucumber6jvm/AllureCucumber6Jvm.java b/allure-cucumber6-jvm/src/main/java/io/qameta/allure/cucumber6jvm/AllureCucumber6Jvm.java index e8c71e51..67f11b0a 100644 --- a/allure-cucumber6-jvm/src/main/java/io/qameta/allure/cucumber6jvm/AllureCucumber6Jvm.java +++ b/allure-cucumber6-jvm/src/main/java/io/qameta/allure/cucumber6jvm/AllureCucumber6Jvm.java @@ -65,6 +65,8 @@ import java.util.stream.Stream; import static io.qameta.allure.util.ResultsUtils.createParameter; +import static io.qameta.allure.util.ResultsUtils.createTitlePath; +import static io.qameta.allure.util.ResultsUtils.createTitlePathFromSourcePath; import static io.qameta.allure.util.ResultsUtils.getStatus; import static io.qameta.allure.util.ResultsUtils.getStatusDetails; import static io.qameta.allure.util.ResultsUtils.md5; @@ -145,11 +147,15 @@ private void handleTestCaseStarted(final TestCaseStarted event) { final String testCaseUuid = testCase.getId().toString(); + final List titlePath = createTitlePathFromSourcePath(getTestCaseUri(testCase)); + titlePath.addAll(createTitlePath(feature.getName())); + final TestResult result = new TestResult() .setUuid(testCaseUuid) .setTestCaseId(getTestCaseId(testCase)) .setHistoryId(getHistoryId(testCase)) .setFullName(fullName) + .setTitlePath(titlePath) .setName(name) .setLabels(labelBuilder.getScenarioLabels()) .setLinks(labelBuilder.getScenarioLinks()); diff --git a/allure-cucumber6-jvm/src/test/java/io/qameta/allure/cucumber6jvm/AllureCucumber6JvmTest.java b/allure-cucumber6-jvm/src/test/java/io/qameta/allure/cucumber6jvm/AllureCucumber6JvmTest.java index 75cc8495..50c32afa 100644 --- a/allure-cucumber6-jvm/src/test/java/io/qameta/allure/cucumber6jvm/AllureCucumber6JvmTest.java +++ b/allure-cucumber6-jvm/src/test/java/io/qameta/allure/cucumber6jvm/AllureCucumber6JvmTest.java @@ -80,6 +80,8 @@ void shouldSetName() { assertThat(testResults) .extracting(TestResult::getName) .containsExactlyInAnyOrder("Add a to b"); + assertThat(testResults.get(0).getTitlePath()) + .containsExactly("src", "test", "resources", "features", "simple.feature", "Simple feature"); } @AllureFeatures.PassedTests diff --git a/allure-cucumber7-jvm/src/main/java/io/qameta/allure/cucumber7jvm/AllureCucumber7Jvm.java b/allure-cucumber7-jvm/src/main/java/io/qameta/allure/cucumber7jvm/AllureCucumber7Jvm.java index 60883143..adac06df 100644 --- a/allure-cucumber7-jvm/src/main/java/io/qameta/allure/cucumber7jvm/AllureCucumber7Jvm.java +++ b/allure-cucumber7-jvm/src/main/java/io/qameta/allure/cucumber7jvm/AllureCucumber7Jvm.java @@ -66,6 +66,8 @@ import java.util.stream.Stream; import static io.qameta.allure.util.ResultsUtils.createParameter; +import static io.qameta.allure.util.ResultsUtils.createTitlePath; +import static io.qameta.allure.util.ResultsUtils.createTitlePathFromSourcePath; import static io.qameta.allure.util.ResultsUtils.getStatus; import static io.qameta.allure.util.ResultsUtils.getStatusDetails; import static io.qameta.allure.util.ResultsUtils.md5; @@ -146,11 +148,15 @@ private void handleTestCaseStarted(final TestCaseStarted event) { final String testCaseUuid = testCase.getId().toString(); + final List titlePath = createTitlePathFromSourcePath(getTestCaseUri(testCase)); + titlePath.addAll(createTitlePath(feature.getName())); + final TestResult result = new TestResult() .setUuid(testCaseUuid) .setTestCaseId(getTestCaseId(testCase)) .setHistoryId(getHistoryId(testCase)) .setFullName(fullName) + .setTitlePath(titlePath) .setName(name) .setLabels(labelBuilder.getScenarioLabels()) .setLinks(labelBuilder.getScenarioLinks()); diff --git a/allure-cucumber7-jvm/src/test/java/io/qameta/allure/cucumber7jvm/AllureCucumber7JvmTest.java b/allure-cucumber7-jvm/src/test/java/io/qameta/allure/cucumber7jvm/AllureCucumber7JvmTest.java index 0d8a20a7..ed1acc53 100644 --- a/allure-cucumber7-jvm/src/test/java/io/qameta/allure/cucumber7jvm/AllureCucumber7JvmTest.java +++ b/allure-cucumber7-jvm/src/test/java/io/qameta/allure/cucumber7jvm/AllureCucumber7JvmTest.java @@ -80,6 +80,8 @@ void shouldSetName() { assertThat(testResults) .extracting(TestResult::getName) .containsExactlyInAnyOrder("Add a to b"); + assertThat(testResults.get(0).getTitlePath()) + .containsExactly("src", "test", "resources", "features", "simple.feature", "Simple feature"); } @AllureFeatures.PassedTests diff --git a/allure-java-commons/src/main/java/io/qameta/allure/util/ResultsUtils.java b/allure-java-commons/src/main/java/io/qameta/allure/util/ResultsUtils.java index 38faa3a5..9e8b28ed 100644 --- a/allure-java-commons/src/main/java/io/qameta/allure/util/ResultsUtils.java +++ b/allure-java-commons/src/main/java/io/qameta/allure/util/ResultsUtils.java @@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; @@ -40,16 +41,21 @@ import java.lang.reflect.Method; import java.math.BigInteger; import java.net.InetAddress; +import java.net.URI; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.function.Consumer; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -98,6 +104,7 @@ public final class ResultsUtils { private static final Logger LOGGER = LoggerFactory.getLogger(ResultsUtils.class); private static final String ALLURE_DESCRIPTIONS_FOLDER = "META-INF/allureDescriptions/"; private static final String MD_5 = "MD5"; + private static final String DOT = "."; private static String cachedHost; @@ -142,6 +149,51 @@ public static Label createPackageLabel(final String packageName) { return createLabel(PACKAGE_LABEL_NAME, packageName); } + public static List createTitlePath(final String... values) { + return createTitlePath(Arrays.asList(values)); + } + + public static List createTitlePath(final Collection values) { + if (Objects.isNull(values)) { + return new ArrayList<>(); + } + return values.stream() + .filter(Objects::nonNull) + .map(String::trim) + .filter(value -> !value.isEmpty()) + .collect(Collectors.toList()); + } + + public static List createTitlePathFromPackageAndClass(final String packageName, final String className) { + final List result = createTitlePathFromPackage(packageName); + getClassTitle(packageName, className).ifPresent(result::add); + return result; + } + + public static List createTitlePathFromQualifiedClassName(final String className) { + return getPackageName(className) + .map(packageName -> createTitlePathFromPackageAndClass(packageName, className)) + .orElseGet(() -> createTitlePath(className)); + } + + public static List createTitlePathFromJavaClass(final Class clazz) { + if (Objects.isNull(clazz)) { + return createTitlePath(); + } + final String packageName = Optional.ofNullable(clazz.getPackage()) + .map(Package::getName) + .orElse(""); + return createTitlePathFromPackageAndClass(packageName, clazz.getName()); + } + + public static List createTitlePathFromPackage(final String packageName) { + return split(packageName, DOT); + } + + public static List createTitlePathFromSourcePath(final String sourcePath) { + return split(normalizeSourcePath(sourcePath), "/"); + } + public static Label createEpicLabel(final String epic) { return createLabel(EPIC_LABEL_NAME, epic); } @@ -474,6 +526,64 @@ private static Optional formatLambdaName(final SerializedLambda lambda) return Optional.of(simpleClassName(lambda.getImplClass()) + "::" + getLambdaMethodName(methodName)); } + private static Optional getPackageName(final String className) { + if (Objects.isNull(className)) { + return Optional.empty(); + } + final int index = className.lastIndexOf('.'); + if (index < 0) { + return Optional.empty(); + } + return Optional.of(className.substring(0, index)); + } + + private static Optional getClassTitle(final String packageName, final String className) { + if (Objects.isNull(className) || className.isEmpty()) { + return Optional.empty(); + } + final String prefix = packageName + DOT; + if (!packageName.isEmpty() && className.startsWith(prefix)) { + return Optional.of(className.substring(prefix.length())); + } + return Optional.of(className); + } + + private static List split(final String value, final String delimiter) { + if (Objects.isNull(value) || value.isEmpty()) { + return new ArrayList<>(); + } + return Stream.of(value.split(Pattern.quote(delimiter))) + .map(String::trim) + .filter(item -> !item.isEmpty()) + .collect(Collectors.toList()); + } + + private static String normalizeSourcePath(final String sourcePath) { + if (Objects.isNull(sourcePath)) { + return ""; + } + try { + final URI uri = URI.create(sourcePath); + if (nonNull(uri.getScheme())) { + final URI normalized = uri.normalize(); + if (!normalized.isOpaque()) { + final URI relative = new File("").toURI().relativize(normalized); + final String path = relative.getPath(); + if (nonNull(path) && !path.isEmpty()) { + return path.replace('\\', '/'); + } + } + final String schemeSpecificPart = normalized.getSchemeSpecificPart(); + if (nonNull(schemeSpecificPart)) { + return schemeSpecificPart.replace('\\', '/'); + } + } + } catch (IllegalArgumentException ignored) { + // Fall back to plain path normalization below. + } + return sourcePath.replace('\\', '/'); + } + private static String getLambdaMethodName(final String methodName) { if ("".equals(methodName)) { return "new"; diff --git a/allure-java-commons/src/test/java/io/qameta/allure/FileSystemResultsWriterTest.java b/allure-java-commons/src/test/java/io/qameta/allure/FileSystemResultsWriterTest.java index e84be69b..4433340f 100644 --- a/allure-java-commons/src/test/java/io/qameta/allure/FileSystemResultsWriterTest.java +++ b/allure-java-commons/src/test/java/io/qameta/allure/FileSystemResultsWriterTest.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.UUID; import static io.qameta.allure.FileSystemResultsWriter.generateTestResultName; @@ -56,6 +57,22 @@ void shouldWriteTestResult(@TempDir final Path folder) { .isRegularFile(); } + @Test + void shouldWriteTitlePath(@TempDir final Path folder) throws IOException { + FileSystemResultsWriter writer = new FileSystemResultsWriter(folder); + final String uuid = UUID.randomUUID().toString(); + final TestResult testResult = new TestResult() + .setUuid(uuid) + .setTitlePath(Arrays.asList("parent", "child")); + + writer.write(testResult); + + assertThat(Files.readString(folder.resolve(generateTestResultName(uuid)))) + .contains("\"titlePath\"") + .contains("\"parent\"") + .contains("\"child\""); + } + @Test void shouldPreserveOldResultsWhenCleanIsDisabled(@TempDir final Path folder) throws IOException { Path existingFile = folder.resolve("existing-result.json"); diff --git a/allure-java-commons/src/test/java/io/qameta/allure/ResultsUtilsTest.java b/allure-java-commons/src/test/java/io/qameta/allure/ResultsUtilsTest.java index dea5482c..a6ee55ed 100644 --- a/allure-java-commons/src/test/java/io/qameta/allure/ResultsUtilsTest.java +++ b/allure-java-commons/src/test/java/io/qameta/allure/ResultsUtilsTest.java @@ -34,6 +34,9 @@ import static io.qameta.allure.util.ResultsUtils.TMS_LINK_TYPE; import static io.qameta.allure.util.ResultsUtils.createIssueLink; import static io.qameta.allure.util.ResultsUtils.createLink; +import static io.qameta.allure.util.ResultsUtils.createTitlePath; +import static io.qameta.allure.util.ResultsUtils.createTitlePathFromQualifiedClassName; +import static io.qameta.allure.util.ResultsUtils.createTitlePathFromSourcePath; import static io.qameta.allure.util.ResultsUtils.createTmsLink; import static io.qameta.allure.util.ResultsUtils.getLinkTypePatternPropertyName; import static org.assertj.core.api.Assertions.assertThat; @@ -44,6 +47,24 @@ @ExtendWith(SystemPropertyExtension.class) class ResultsUtilsTest { + @Test + void shouldCreateTitlePath() { + assertThat(createTitlePath(" parent ", null, " ", "child")) + .containsExactly("parent", "child"); + } + + @Test + void shouldCreateTitlePathFromQualifiedClassName() { + assertThat(createTitlePathFromQualifiedClassName("io.qameta.allure.samples.MyTest")) + .containsExactly("io", "qameta", "allure", "samples", "MyTest"); + } + + @Test + void shouldCreateTitlePathFromSourcePath() { + assertThat(createTitlePathFromSourcePath("features/nested/my.test.feature")) + .containsExactly("features", "nested", "my.test.feature"); + } + @Test void shouldCreateLink() { io.qameta.allure.model.Link actual = createLink("a", "b", "c", "d"); diff --git a/allure-jbehave/src/main/java/io/qameta/allure/jbehave/AllureJbehave.java b/allure-jbehave/src/main/java/io/qameta/allure/jbehave/AllureJbehave.java index 2acd047d..0c19cd24 100644 --- a/allure-jbehave/src/main/java/io/qameta/allure/jbehave/AllureJbehave.java +++ b/allure-jbehave/src/main/java/io/qameta/allure/jbehave/AllureJbehave.java @@ -50,6 +50,7 @@ import static io.qameta.allure.util.ResultsUtils.createParameter; import static io.qameta.allure.util.ResultsUtils.createStoryLabel; import static io.qameta.allure.util.ResultsUtils.createThreadLabel; +import static io.qameta.allure.util.ResultsUtils.createTitlePath; import static io.qameta.allure.util.ResultsUtils.getMd5Digest; import static io.qameta.allure.util.ResultsUtils.getStatus; import static io.qameta.allure.util.ResultsUtils.getStatusDetails; @@ -245,6 +246,7 @@ protected void startTestCase(final String uuid, .setName(name) .setFullName(fullName) .setStage(Stage.SCHEDULED) + .setTitlePath(getTitlePath(story)) .setLabels(labels) .setParameters(parameters) .setDescription(story.getDescription().asString()) @@ -254,6 +256,13 @@ protected void startTestCase(final String uuid, getLifecycle().startTestCase(result.getUuid()); } + private List getTitlePath(final Story story) { + if (story.getPath() == null) { + return createTitlePath(); + } + return createTitlePath(Arrays.asList(story.getPath().replace('\\', '/').split("/"))); + } + protected void stopTestCase(final String uuid) { getLifecycle().stopTestCase(uuid); getLifecycle().writeTestCase(uuid); diff --git a/allure-jbehave/src/test/java/io/qameta/allure/jbehave/AllureJbehaveTest.java b/allure-jbehave/src/test/java/io/qameta/allure/jbehave/AllureJbehaveTest.java index c57a6e45..1a465077 100644 --- a/allure-jbehave/src/test/java/io/qameta/allure/jbehave/AllureJbehaveTest.java +++ b/allure-jbehave/src/test/java/io/qameta/allure/jbehave/AllureJbehaveTest.java @@ -167,6 +167,8 @@ void shouldSetFullName() { assertThat(results.getTestResults()) .extracting(TestResult::getFullName) .containsExactlyInAnyOrder("simple.story: Add a to b"); + assertThat(results.getTestResults().get(0).getTitlePath()) + .containsExactly("stories", "simple.story"); } @Test diff --git a/allure-jbehave5/src/main/java/io/qameta/allure/jbehave5/AllureJbehave5.java b/allure-jbehave5/src/main/java/io/qameta/allure/jbehave5/AllureJbehave5.java index 81e34736..1e54bd0d 100644 --- a/allure-jbehave5/src/main/java/io/qameta/allure/jbehave5/AllureJbehave5.java +++ b/allure-jbehave5/src/main/java/io/qameta/allure/jbehave5/AllureJbehave5.java @@ -54,6 +54,7 @@ import static io.qameta.allure.util.ResultsUtils.createParameter; import static io.qameta.allure.util.ResultsUtils.createStoryLabel; import static io.qameta.allure.util.ResultsUtils.createThreadLabel; +import static io.qameta.allure.util.ResultsUtils.createTitlePath; import static io.qameta.allure.util.ResultsUtils.getMd5Digest; import static io.qameta.allure.util.ResultsUtils.getStatus; import static io.qameta.allure.util.ResultsUtils.getStatusDetails; @@ -245,6 +246,7 @@ protected void startTestCase(final String uuid, .setName(name) .setFullName(fullName) .setStage(Stage.SCHEDULED) + .setTitlePath(getTitlePath(story)) .setLabels(labels) .setParameters(parameters) .setDescription(story.getDescription().asString()) @@ -254,6 +256,13 @@ protected void startTestCase(final String uuid, getLifecycle().startTestCase(result.getUuid()); } + private List getTitlePath(final Story story) { + if (story.getPath() == null) { + return createTitlePath(); + } + return createTitlePath(Arrays.asList(story.getPath().replace('\\', '/').split("/"))); + } + protected void stopTestCase(final String uuid) { getLifecycle().stopTestCase(uuid); getLifecycle().writeTestCase(uuid); diff --git a/allure-jbehave5/src/test/java/io/qameta/allure/jbehave5/AllureJbehave5Test.java b/allure-jbehave5/src/test/java/io/qameta/allure/jbehave5/AllureJbehave5Test.java index 1c5c153d..1b9596d5 100644 --- a/allure-jbehave5/src/test/java/io/qameta/allure/jbehave5/AllureJbehave5Test.java +++ b/allure-jbehave5/src/test/java/io/qameta/allure/jbehave5/AllureJbehave5Test.java @@ -166,6 +166,8 @@ void shouldSetFullName() { assertThat(results.getTestResults()) .extracting(TestResult::getFullName) .containsExactlyInAnyOrder("simple.story: Add a to b"); + assertThat(results.getTestResults().get(0).getTitlePath()) + .containsExactly("stories", "simple.story"); } @Test diff --git a/allure-junit-platform/src/main/java/io/qameta/allure/junitplatform/AllureJunitPlatform.java b/allure-junit-platform/src/main/java/io/qameta/allure/junitplatform/AllureJunitPlatform.java index a336ee2a..f33f45e5 100644 --- a/allure-junit-platform/src/main/java/io/qameta/allure/junitplatform/AllureJunitPlatform.java +++ b/allure-junit-platform/src/main/java/io/qameta/allure/junitplatform/AllureJunitPlatform.java @@ -523,6 +523,7 @@ private void startTestCase(final TestIdentifier testIdentifier) { ? maybeParent.get().getDisplayName() + " " + testIdentifier.getDisplayName() : testIdentifier.getDisplayName() ) + .setTitlePath(getTitlePath(testIdentifier, testClass)) .setLabels(getTags(testIdentifier)) .setTestCaseId(testTemplate ? maybeParent.map(TestIdentifier::getUniqueId) @@ -662,6 +663,52 @@ private List