Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,23 @@ public Optional<Path> featuresOrStoriesRootDirectory() {
URI serenityReqDir = new File(ThucydidesSystemProperty.SERENITY_REQUIREMENTS_DIR.from(environmentVariables)).toURI();
return Optional.of(Paths.get(serenityReqDir));
}

// The Gradle plugin's `AggregateTask` wires its `requirementsBaseDir` DSL field
// into `serenity.test.requirements.basedir`, but does not mirror it into
// `serenity.requirements.dir`. For multi-module Gradle builds the working
// directory during aggregation is the root project (not the sub-module owning
// the feature files), so the classpath / resource scans below do not find the
// feature tree. Honouring the `basedir` property here makes the existing
// plugin wiring work without requiring callers to double-configure the same
// path under two property names.
if (ThucydidesSystemProperty.SERENITY_TEST_REQUIREMENTS_BASEDIR.isDefinedIn(environmentVariables)) {
File basedir = new File(
ThucydidesSystemProperty.SERENITY_TEST_REQUIREMENTS_BASEDIR.from(environmentVariables));
if (basedir.isDirectory()) {
return Optional.of(basedir.toPath());
}
}

List<File> resourceDirectories = getResourceDirectories(Paths.get(relativeRoot), environmentVariables);
List<File> resourceDirectoriesByIncreasingDepth = resourceDirectories.stream()
.sorted(Comparator.comparingInt(dir -> dir.getAbsolutePath().length()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@
import net.thucydides.model.environment.MockEnvironmentVariables;
import net.thucydides.model.util.EnvironmentVariables;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class WhenFindingTheRootDirectoryForFeatureFiles {

EnvironmentVariables environmentVariables = new MockEnvironmentVariables();
Expand All @@ -24,4 +31,54 @@ void withADefinedProjectDirectory() {
RootDirectory rootDirectory = new RootDirectory(environmentVariables,featureDirectory);
Set<String> directoryPaths = rootDirectory.getRootDirectoryPaths();
}

@Test
void featuresOrStoriesRootDirectoryFallsBackToTestRequirementsBasedir(@TempDir Path tempDir) throws Exception {
// Simulates the Gradle plugin's AggregateTask wiring: `requirementsBaseDir` is set,
// but `serenity.requirements.dir` is not. featuresOrStoriesRootDirectory() should
// pick up the basedir instead of falling through to the working-directory scan
// (which misfires in multi-module Gradle builds because user.dir == root project).
Path featuresDir = tempDir.resolve("features");
Files.createDirectories(featuresDir);

environmentVariables.setProperty("serenity.test.requirements.basedir", featuresDir.toString());

RootDirectory rootDirectory = new RootDirectory(environmentVariables, ".");
Optional<Path> resolved = rootDirectory.featuresOrStoriesRootDirectory();

assertTrue(resolved.isPresent(), "Expected featuresOrStoriesRootDirectory() to honour serenity.test.requirements.basedir");
assertEquals(featuresDir.toAbsolutePath(), resolved.get().toAbsolutePath());
}

@Test
void serenityRequirementsDirTakesPrecedenceOverBasedir(@TempDir Path tempDir) throws Exception {
// When both properties are set, the existing behaviour (SERENITY_REQUIREMENTS_DIR wins)
// must be preserved — the new fallback must not regress that order.
Path primary = tempDir.resolve("primary/features");
Path fallback = tempDir.resolve("fallback/features");
Files.createDirectories(primary);
Files.createDirectories(fallback);

environmentVariables.setProperty("serenity.requirements.dir", primary.toString());
environmentVariables.setProperty("serenity.test.requirements.basedir", fallback.toString());

Optional<Path> resolved = new RootDirectory(environmentVariables, ".").featuresOrStoriesRootDirectory();

assertTrue(resolved.isPresent());
assertEquals(primary.toAbsolutePath(), resolved.get().toAbsolutePath());
}

@Test
void basedirFallbackIgnoresNonExistentPaths(@TempDir Path tempDir) {
// Guard against a stale basedir value masking the classpath/working-dir fallback.
String nonExistent = tempDir.resolve("does-not-exist").toString();
environmentVariables.setProperty("serenity.test.requirements.basedir", nonExistent);

Optional<Path> resolved = new RootDirectory(environmentVariables, ".").featuresOrStoriesRootDirectory();

// The fallback must not hand back a path that does not exist — callers treat the
// Optional.of(...) result as authoritative.
resolved.ifPresent(path -> assertTrue(path.toFile().exists(),
"featuresOrStoriesRootDirectory() should not return a non-existent basedir: " + path));
}
}
Loading