Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a polling-based step that waits for exactly one file matching a filename regex to appear in a directory (or until timeout), records failures via soft assertions for 0 or multiple matches, and saves the matched file's absolute path into a variable. Changes
Sequence Diagram(s)sequenceDiagram
participant JBehave as "JBehave (Step runner)"
participant FileSteps as "FileSteps"
participant Waiter as "DurationBasedWaiter"
participant FS as "File System"
participant SoftAssert as "ISoftAssert"
participant VarCtx as "VariableContext"
JBehave->>FileSteps: invoke waitForFileAndSavePath(timeout, poll, regex, dir, scopes, varName)
FileSteps->>FileSteps: validate directory exists
FileSteps->>Waiter: start polling (timeout, pollingInterval)
loop polling
Waiter->>FS: list regular files in dir
FS-->>Waiter: filenames
Waiter->>FileSteps: return matches
end
alt exactly one match
FileSteps->>VarCtx: putVariable(scopes, varName, matchedFileAbsolutePath)
else zero matches
FileSteps->>SoftAssert: recordFailedAssertion("No files matching ...")
else multiple matches
FileSteps->>SoftAssert: recordFailedAssertion("Multiple files found: ...")
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #6574 +/- ##
=========================================
Coverage 97.77% 97.77%
Complexity 7417 7417
=========================================
Files 1015 1015
Lines 21464 21484 +20
Branches 1408 1410 +2
=========================================
+ Hits 20987 21007 +20
Misses 361 361
Partials 116 116 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@vividus-tests/src/main/resources/story/integration/File.story`:
- Around line 3-5: The path handling is Windows-incompatible:
createTemporaryFile produces Path.toString() with backslashes so
substringBeforeLast(filePath, '/') and the final assertion
`${folderName}/data.*\.txt` will fail; update the folder extraction (where you
call eval(stringUtils:substringBeforeLast(filePath, '/')) or similar) to be
separator-aware (either use the platform file separator or normalize filePath by
replacing backslashes with forward slashes before taking substringBeforeLast)
and make the final regex separator-agnostic by using a character class for
separators (e.g. use [\\/]) when building the expected path for `${textFile}`
and `${folderName}` comparisons.
- Line 4: The step using the filename regex currently uses `.*.txt` which treats
the dot as "any char" and will match unintended names; update the pattern in the
story step to escape the literal dot (use `.*\.txt`) so it only matches files
ending with the `.txt` extension—change the pattern in the step that reads "When
I wait `PT30S` with `PT1S` polling until file matching `.*.txt` appears in
directory `${folderName}` and save path to scenario variable `textFile`" to use
the escaped form.
In `@vividus/src/main/java/org/vividus/steps/FileSteps.java`:
- Around line 108-110: The stream returned by Files.list(dir) currently matches
directory entries whose names fit fileNameRegex; update the predicate in the
code that builds the Stream<Path> (the try-with-resources using Stream<Path>
paths and the filter that references fileNameRegex) to first restrict to regular
files (Files::isRegularFile or Files::isRegularFile with p) before applying
fileNameRegex.matcher(p.getFileName().toString()).matches(), and add a
unit/regression test that creates a directory named like a matching file (e.g.,
"report-1.csv" as a directory) to assert it is not returned by the method in
FileSteps.java.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: c4e0a57d-5723-4743-af20-828f21930b27
📒 Files selected for processing (4)
docs/modules/commons/pages/vividus-steps.adocvividus-tests/src/main/resources/story/integration/File.storyvividus/src/main/java/org/vividus/steps/FileSteps.javavividus/src/test/java/org/vividus/steps/FileStepsTests.java
Qodana for JVMIt seems all right 👌 No new problems were found according to the checks applied 💡 Qodana analysis was run in the pull request mode: only the changed files were checked Contact Qodana teamContact us at qodana-support@jetbrains.com
|
| When I create temporary file with name `mydata.txt` and content `Hello World!` and put path to scenario variable `filePath` | ||
| Given I initialize scenario variable `folderName` with value `#{eval(stringUtils:substringBefore(filePath, 'mydata'))}` | ||
| When I wait `PT30S` with `PT1S` polling until file matching `.*.txt` appears in directory `${folderName}` and save path to scenario variable `textFile` | ||
| Then `${textFile}` matches `${folderName}mydata.*\.txt` |
There was a problem hiding this comment.
| Then `${textFile}` matches `${folderName}mydata.*\.txt` | |
| Then `${textFile}` is equal to `${filePath}` |
There was a problem hiding this comment.
actual temp file name is mydata2313123123.txt that's why matcher is used
There was a problem hiding this comment.
but shouldn't ${filePath} contain full path to temp file?
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@vividus/src/test/java/org/vividus/steps/FileStepsTests.java`:
- Around line 101-109: Add a regression test in FileStepsTests named
shouldIgnoreDirectoryWithMatchingName that creates a directory named like the
file pattern (e.g., Files.createDirectory(tempDir.resolve("report-99.csv"))),
creates a real file (e.g., "report-42.csv"), calls
fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir,
SCOPES, VARIABLE), and then verifies variableContext.putVariable(SCOPES,
VARIABLE, tempDir.resolve(csv).toAbsolutePath().toString()) and
verifyNoInteractions(softAssert) to ensure directories matching the pattern are
ignored.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 87f8e286-96bc-43b4-b6b2-122f964b087f
📒 Files selected for processing (4)
docs/modules/commons/pages/vividus-steps.adocvividus-tests/src/main/resources/story/integration/FileSteps.storyvividus/src/main/java/org/vividus/steps/FileSteps.javavividus/src/test/java/org/vividus/steps/FileStepsTests.java
| @Test | ||
| void shouldSaveFilePathWhenExactlyOneFileMatches(@TempDir Path tempDir) throws IOException | ||
| { | ||
| String csv = "report-42.csv"; | ||
| Files.createFile(tempDir.resolve(csv)); | ||
| fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir, SCOPES, VARIABLE); | ||
| verify(variableContext).putVariable(SCOPES, VARIABLE, tempDir.resolve(csv).toAbsolutePath().toString()); | ||
| verifyNoInteractions(softAssert); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider adding a regression test for directory filtering.
The implementation correctly filters out directories using Files::isRegularFile, but there's no test verifying that a directory with a matching name (e.g., report-42.csv/) is excluded from results. This would guard against future regressions.
📋 Suggested test case
`@Test`
void shouldIgnoreDirectoryWithMatchingName(`@TempDir` Path tempDir) throws IOException
{
// Create a directory with a name matching the pattern
Files.createDirectory(tempDir.resolve("report-99.csv"));
// Create an actual file
String csv = "report-42.csv";
Files.createFile(tempDir.resolve(csv));
fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir, SCOPES, VARIABLE);
verify(variableContext).putVariable(SCOPES, VARIABLE, tempDir.resolve(csv).toAbsolutePath().toString());
verifyNoInteractions(softAssert);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vividus/src/test/java/org/vividus/steps/FileStepsTests.java` around lines 101
- 109, Add a regression test in FileStepsTests named
shouldIgnoreDirectoryWithMatchingName that creates a directory named like the
file pattern (e.g., Files.createDirectory(tempDir.resolve("report-99.csv"))),
creates a real file (e.g., "report-42.csv"), calls
fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir,
SCOPES, VARIABLE), and then verifies variableContext.putVariable(SCOPES,
VARIABLE, tempDir.resolve(csv).toAbsolutePath().toString()) and
verifyNoInteractions(softAssert) to ensure directories matching the pattern are
ignored.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
vividus-tests/src/main/resources/story/integration/FileSteps.story (1)
4-4:⚠️ Potential issue | 🟡 MinorEscape the literal dot in the test regex.
.*.txtstill treats.as “any character”, so this scenario can match unintended names. Use.*\.txtif the intent is “any.txttemp file”.Suggested fix
-When I wait `PT30S` with `PT1S` polling until file matching `.*.txt` appears in directory `${folderName}` and save path to scenario variable `textFile` +When I wait `PT30S` with `PT1S` polling until file matching `.*\.txt` appears in directory `${folderName}` and save path to scenario variable `textFile`🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@vividus-tests/src/main/resources/story/integration/FileSteps.story` at line 4, The regex in the scenario step "When I wait `PT30S` with `PT1S` polling until file matching `.*.txt` appears..." treats the dot as "any character"; update the pattern to escape the literal dot so it only matches .txt files by changing the pattern from `.*.txt` to `.*\.txt` inside the step in FileSteps.story (the step that saves path to scenario variable `textFile`).vividus/src/test/java/org/vividus/steps/FileStepsTests.java (1)
101-133: 🧹 Nitpick | 🔵 TrivialAdd the missing regression case for matching directories.
The production code now excludes directories via
Files::isRegularFile, but the new tests still don't lock that behavior in. A directory named likereport-99.csvwould currently regress silently here.Suggested test
`@Test` void shouldSaveFilePathWhenExactlyOneFileMatches(`@TempDir` Path tempDir) throws IOException { String csv = "report-42.csv"; Files.createFile(tempDir.resolve(csv)); fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir, SCOPES, VARIABLE); verify(variableContext).putVariable(SCOPES, VARIABLE, tempDir.resolve(csv).toAbsolutePath().toString()); verifyNoInteractions(softAssert); } + +@Test +void shouldIgnoreDirectoryWithMatchingName(`@TempDir` Path tempDir) throws IOException +{ + Files.createDirectory(tempDir.resolve("report-99.csv")); + String csv = "report-42.csv"; + Files.createFile(tempDir.resolve(csv)); + + fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir, SCOPES, VARIABLE); + + verify(variableContext).putVariable(SCOPES, VARIABLE, tempDir.resolve(csv).toAbsolutePath().toString()); + verifyNoInteractions(softAssert); +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@vividus/src/test/java/org/vividus/steps/FileStepsTests.java` around lines 101 - 133, Add a regression test that verifies directories matching the file pattern are ignored by waitForFileAndSavePath: create a directory named like "report-99.csv" inside the TempDir (using Files.createDirectory) and also create the actual file(s) needed for the scenario, then call fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir, SCOPES, VARIABLE) and assert expected behavior (e.g., when only a matching directory exists, recordFailedAssertion is called; when both directory and file exist, only the file is considered and variableContext.putVariable is invoked). Reference the existing test helper and assertions around fileSteps.waitForFileAndSavePath, softAssert.recordFailedAssertion, and variableContext.putVariable to locate where to add the new test(s).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@vividus-tests/src/main/resources/story/integration/FileSteps.story`:
- Line 4: The regex in the scenario step "When I wait `PT30S` with `PT1S`
polling until file matching `.*.txt` appears..." treats the dot as "any
character"; update the pattern to escape the literal dot so it only matches .txt
files by changing the pattern from `.*.txt` to `.*\.txt` inside the step in
FileSteps.story (the step that saves path to scenario variable `textFile`).
In `@vividus/src/test/java/org/vividus/steps/FileStepsTests.java`:
- Around line 101-133: Add a regression test that verifies directories matching
the file pattern are ignored by waitForFileAndSavePath: create a directory named
like "report-99.csv" inside the TempDir (using Files.createDirectory) and also
create the actual file(s) needed for the scenario, then call
fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir,
SCOPES, VARIABLE) and assert expected behavior (e.g., when only a matching
directory exists, recordFailedAssertion is called; when both directory and file
exist, only the file is considered and variableContext.putVariable is invoked).
Reference the existing test helper and assertions around
fileSteps.waitForFileAndSavePath, softAssert.recordFailedAssertion, and
variableContext.putVariable to locate where to add the new test(s).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 01901841-7859-4c6e-81f1-3d8cc09ba297
📒 Files selected for processing (4)
docs/modules/commons/pages/vividus-steps.adocvividus-tests/src/main/resources/story/integration/FileSteps.storyvividus/src/main/java/org/vividus/steps/FileSteps.javavividus/src/test/java/org/vividus/steps/FileStepsTests.java
There was a problem hiding this comment.
♻️ Duplicate comments (1)
vividus/src/test/java/org/vividus/steps/FileStepsTests.java (1)
101-109: 🧹 Nitpick | 🔵 TrivialConsider adding a test case for directory filtering.
The tests cover the main scenarios well. As noted in a previous review, adding a regression test that creates a directory with a matching name (e.g.,
report-99.csv/) and verifying it gets filtered out would strengthen coverage of theFiles::isRegularFilefilter in the implementation.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@vividus/src/test/java/org/vividus/steps/FileStepsTests.java` around lines 101 - 109, Add a regression test in FileStepsTests that ensures directories with matching names are ignored by the Files::isRegularFile filter: create a directory whose name matches the file pattern (e.g., Files.createDirectory(tempDir.resolve("report-99.csv"))) alongside a real matching file (or reuse the existing file creation), call fileSteps.waitForFileAndSavePath(...) and verify variableContext.putVariable(...) is called with the real file's absolute path and not the directory; reference the existing test method shouldSaveFilePathWhenExactlyOneFileMatches to mirror setup and assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@vividus/src/test/java/org/vividus/steps/FileStepsTests.java`:
- Around line 101-109: Add a regression test in FileStepsTests that ensures
directories with matching names are ignored by the Files::isRegularFile filter:
create a directory whose name matches the file pattern (e.g.,
Files.createDirectory(tempDir.resolve("report-99.csv"))) alongside a real
matching file (or reuse the existing file creation), call
fileSteps.waitForFileAndSavePath(...) and verify
variableContext.putVariable(...) is called with the real file's absolute path
and not the directory; reference the existing test method
shouldSaveFilePathWhenExactlyOneFileMatches to mirror setup and assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: dae3d0e2-a439-40f2-8df8-012d2c2c49c6
📒 Files selected for processing (4)
docs/modules/commons/pages/vividus-steps.adocvividus-tests/src/main/resources/story/integration/FileSteps.storyvividus/src/main/java/org/vividus/steps/FileSteps.javavividus/src/test/java/org/vividus/steps/FileStepsTests.java
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/modules/commons/pages/vividus-steps.adoc`:
- Around line 475-496: Add a one-line failure semantics note to the "Wait for a
file to appear in a directory" step description clarifying that if the poll
times out with zero matches or if multiple files match `$fileNameRegex` (not
just the full path) this results in a soft-assertion failure and the target
variable `$variableName` is not set, so downstream steps referencing
`$variableName` may fail; place this sentence near the paragraph that currently
explains `exactly one file` alongside the parameter list (`$timeout`,
`$pollingTimeout`, `$fileNameRegex`, `$directoryPath`, `$scopes`,
`$variableName`) so readers see the behavior immediately.
In `@vividus/src/main/java/org/vividus/steps/FileSteps.java`:
- Around line 118-133: Replace the positional access found.get(0) with the
clearer first-element accessor found.getFirst() in the success branch of the
block handling found files; update the declaration/collection type of found (or
how it is constructed) so that getFirst() is available (e.g., use
LinkedList<Path> or Deque<Path> instead of List<Path>) and keep the call to
variableContext.putVariable(scopes, variableName,
found.getFirst().toAbsolutePath().toString()); ensure any imports or stream
collectors that build found are adjusted accordingly (references:
variableContext.putVariable, found, fileNameRegex, directoryPath, timeout).
In `@vividus/src/test/java/org/vividus/steps/FileStepsTests.java`:
- Around line 121-134: The test shouldFailWhenMultipleFilesMatch can be
simplified by removing the ArgumentCaptor and asserting the deterministic
failure message directly: call fileSteps.waitForFileAndSavePath(...) as before,
then verify that softAssert.recordFailedAssertion was called with the exact
expected string (constructed using FILE_PATTERN and tempDir and the sorted
filenames "report-1.csv, report-2.csv"), and keep
verifyNoInteractions(variableContext); remove the ArgumentCaptor import and its
usage and replace the capture/assertEquals block with a direct
verify(softAssert).recordFailedAssertion(expectedMessage) assertion referencing
the method names shown.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d0416b60-00b5-4b80-93f0-4c07c28f8089
📒 Files selected for processing (4)
docs/modules/commons/pages/vividus-steps.adocvividus-tests/src/main/resources/story/integration/FileSteps.storyvividus/src/main/java/org/vividus/steps/FileSteps.javavividus/src/test/java/org/vividus/steps/FileStepsTests.java
| === Wait for a file to appear in a directory | ||
|
|
||
| Polls the given directory until exactly one file whose name matches the regular expression appears or the timeout | ||
| expires, then saves the absolute path of that file to a variable. | ||
|
|
||
| [source,gherkin] | ||
| ---- | ||
| When I wait `$timeout` with `$pollingTimeout` polling until file matching `$fileNameRegex` appears in directory `$directoryPath` and save path to $scopes variable `$variableName` | ||
| ---- | ||
|
|
||
| * `$timeout` - The maximum time to wait in {durations-format-link} format. | ||
| * `$pollingTimeout` - The interval between polling attempts in {durations-format-link} format. | ||
| * `$fileNameRegex` - The regular expression matched against file names only (not the full path), e.g. `report-\d+\.csv`. | ||
| * `$directoryPath` - The path to an existing directory to watch. | ||
| * `$scopes` - xref:commons:variables.adoc#_scopes[The comma-separated set of the variables scopes]. | ||
| * `$variableName` - The name of the variable to store the absolute path of the matched file. | ||
|
|
||
| .Wait up to 30 seconds for a CSV report to arrive and store its path | ||
| [source,gherkin] | ||
| ---- | ||
| When I wait `PT30S` with `PT1S` polling until file matching `report-\d+\.csv` appears in directory `/tmp/reports` and save path to SCENARIO variable `report-path` | ||
| ---- |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Document the failure semantics (zero vs. multiple matches) and that $variableName is not set on failure.
The intro mentions polling until "exactly one file" appears but doesn't explicitly state that: (a) finding zero files at timeout and (b) finding multiple matching files both result in soft-assertion failures, and (c) the target variable is not set in those cases — which affects any downstream steps referencing it. A one-liner would prevent surprises.
✍️ Proposed addition
Polls the given directory until exactly one file whose name matches the regular expression appears or the timeout
expires, then saves the absolute path of that file to a variable.
+
+If no matching file appears within the timeout, or if more than one matching file is found during polling, a soft
+assertion failure is recorded and the variable is not set.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| === Wait for a file to appear in a directory | |
| Polls the given directory until exactly one file whose name matches the regular expression appears or the timeout | |
| expires, then saves the absolute path of that file to a variable. | |
| [source,gherkin] | |
| ---- | |
| When I wait `$timeout` with `$pollingTimeout` polling until file matching `$fileNameRegex` appears in directory `$directoryPath` and save path to $scopes variable `$variableName` | |
| ---- | |
| * `$timeout` - The maximum time to wait in {durations-format-link} format. | |
| * `$pollingTimeout` - The interval between polling attempts in {durations-format-link} format. | |
| * `$fileNameRegex` - The regular expression matched against file names only (not the full path), e.g. `report-\d+\.csv`. | |
| * `$directoryPath` - The path to an existing directory to watch. | |
| * `$scopes` - xref:commons:variables.adoc#_scopes[The comma-separated set of the variables scopes]. | |
| * `$variableName` - The name of the variable to store the absolute path of the matched file. | |
| .Wait up to 30 seconds for a CSV report to arrive and store its path | |
| [source,gherkin] | |
| ---- | |
| When I wait `PT30S` with `PT1S` polling until file matching `report-\d+\.csv` appears in directory `/tmp/reports` and save path to SCENARIO variable `report-path` | |
| ---- | |
| === Wait for a file to appear in a directory | |
| Polls the given directory until exactly one file whose name matches the regular expression appears or the timeout | |
| expires, then saves the absolute path of that file to a variable. | |
| If no matching file appears within the timeout, or if more than one matching file is found during polling, a soft | |
| assertion failure is recorded and the variable is not set. | |
| [source,gherkin] | |
| ---- | |
| When I wait `$timeout` with `$pollingTimeout` polling until file matching `$fileNameRegex` appears in directory `$directoryPath` and save path to $scopes variable `$variableName` | |
| ---- | |
| * `$timeout` - The maximum time to wait in {durations-format-link} format. | |
| * `$pollingTimeout` - The interval between polling attempts in {durations-format-link} format. | |
| * `$fileNameRegex` - The regular expression matched against file names only (not the full path), e.g. `report-\d+\.csv`. | |
| * `$directoryPath` - The path to an existing directory to watch. | |
| * `$scopes` - xref:commons:variables.adoc#_scopes[The comma-separated set of the variables scopes]. | |
| * `$variableName` - The name of the variable to store the absolute path of the matched file. | |
| .Wait up to 30 seconds for a CSV report to arrive and store its path | |
| [source,gherkin] | |
| ---- | |
| When I wait `PT30S` with `PT1S` polling until file matching `report-\d+\.csv` appears in directory `/tmp/reports` and save path to SCENARIO variable `report-path` | |
| ---- |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/modules/commons/pages/vividus-steps.adoc` around lines 475 - 496, Add a
one-line failure semantics note to the "Wait for a file to appear in a
directory" step description clarifying that if the poll times out with zero
matches or if multiple files match `$fileNameRegex` (not just the full path)
this results in a soft-assertion failure and the target variable `$variableName`
is not set, so downstream steps referencing `$variableName` may fail; place this
sentence near the paragraph that currently explains `exactly one file` alongside
the parameter list (`$timeout`, `$pollingTimeout`, `$fileNameRegex`,
`$directoryPath`, `$scopes`, `$variableName`) so readers see the behavior
immediately.
| if (found.size() > 1) | ||
| { | ||
| List<String> fileNames = found.stream().map(Path::getFileName).map(Path::toString).sorted().toList(); | ||
| softAssert | ||
| .recordFailedAssertion("Expected exactly 1 file matching `%s` in directory '%s', but found %d: %s." | ||
| .formatted(fileNameRegex, directoryPath, found.size(), String.join(", ", fileNames))); | ||
| } | ||
| else if (found.isEmpty()) | ||
| { | ||
| softAssert.recordFailedAssertion("No file matching `%s` appeared in directory '%s' within %s" | ||
| .formatted(fileNameRegex, directoryPath, timeout)); | ||
| } | ||
| else | ||
| { | ||
| variableContext.putVariable(scopes, variableName, found.get(0).toAbsolutePath().toString()); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
🌐 Web query:
What is the minimum Java version required by the vividus-framework/vividus project on master?
💡 Result:
The minimum Java version required by the vividus-framework/vividus project on master is Java 21.
Citations:
- 1: https://github.com/vividus-framework/vividus
- 2: https://github.com/vividus-framework/vividus/blob/master/README.md
🏁 Script executed:
find . -name "FileSteps.java" -type fRepository: vividus-framework/vividus
Length of output: 125
🏁 Script executed:
sed -n '118,133p' ./vividus/src/main/java/org/vividus/steps/FileSteps.javaRepository: vividus-framework/vividus
Length of output: 860
Prefer List.getFirst() over get(0) for better readability.
Since the project targets Java 21+, getFirst() is available and expresses intent more clearly.
♻️ Proposed change
- variableContext.putVariable(scopes, variableName, found.get(0).toAbsolutePath().toString());
+ variableContext.putVariable(scopes, variableName, found.getFirst().toAbsolutePath().toString());🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vividus/src/main/java/org/vividus/steps/FileSteps.java` around lines 118 -
133, Replace the positional access found.get(0) with the clearer first-element
accessor found.getFirst() in the success branch of the block handling found
files; update the declaration/collection type of found (or how it is
constructed) so that getFirst() is available (e.g., use LinkedList<Path> or
Deque<Path> instead of List<Path>) and keep the call to
variableContext.putVariable(scopes, variableName,
found.getFirst().toAbsolutePath().toString()); ensure any imports or stream
collectors that build found are adjusted accordingly (references:
variableContext.putVariable, found, fileNameRegex, directoryPath, timeout).
| @Test | ||
| void shouldFailWhenMultipleFilesMatch(@TempDir Path tempDir) throws IOException | ||
| { | ||
| Files.createFile(tempDir.resolve("report-1.csv")); | ||
| Files.createFile(tempDir.resolve("report-2.csv")); | ||
| fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir, SCOPES, VARIABLE); | ||
| var messageCaptor = ArgumentCaptor.forClass(String.class); | ||
| verify(softAssert).recordFailedAssertion(messageCaptor.capture()); | ||
| assertEquals( | ||
| "Expected exactly 1 file matching `%s` in directory '%s', but found 2: report-1.csv, report-2.csv." | ||
| .formatted(FILE_PATTERN, tempDir), | ||
| messageCaptor.getValue()); | ||
| verifyNoInteractions(variableContext); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Simplify: drop ArgumentCaptor — the expected message is deterministic.
Filenames are sorted before being joined, so the expected assertion message is fully deterministic and you can verify it directly.
♻️ Proposed simplification
- fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir, SCOPES, VARIABLE);
- var messageCaptor = ArgumentCaptor.forClass(String.class);
- verify(softAssert).recordFailedAssertion(messageCaptor.capture());
- assertEquals(
- "Expected exactly 1 file matching `%s` in directory '%s', but found 2: report-1.csv, report-2.csv."
- .formatted(FILE_PATTERN, tempDir),
- messageCaptor.getValue());
- verifyNoInteractions(variableContext);
+ fileSteps.waitForFileAndSavePath(TIMEOUT, TIMEOUT, FILE_PATTERN, tempDir, SCOPES, VARIABLE);
+ verify(softAssert).recordFailedAssertion(
+ "Expected exactly 1 file matching `%s` in directory '%s', but found 2: report-1.csv, report-2.csv."
+ .formatted(FILE_PATTERN, tempDir));
+ verifyNoInteractions(variableContext);You can then remove the ArgumentCaptor import.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vividus/src/test/java/org/vividus/steps/FileStepsTests.java` around lines 121
- 134, The test shouldFailWhenMultipleFilesMatch can be simplified by removing
the ArgumentCaptor and asserting the deterministic failure message directly:
call fileSteps.waitForFileAndSavePath(...) as before, then verify that
softAssert.recordFailedAssertion was called with the exact expected string
(constructed using FILE_PATTERN and tempDir and the sorted filenames
"report-1.csv, report-2.csv"), and keep verifyNoInteractions(variableContext);
remove the ArgumentCaptor import and its usage and replace the
capture/assertEquals block with a direct
verify(softAssert).recordFailedAssertion(expectedMessage) assertion referencing
the method names shown.
|



Summary by CodeRabbit
New Features
Documentation
Tests
Bug Fixes