This is an automated email from the ASF dual-hosted git repository.
vladimirsitnikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jmeter.git
The following commit(s) were added to refs/heads/master by this push:
new 957aeaccc7 fix: report generation used wrong paths for the output files
957aeaccc7 is described below
commit 957aeaccc706319e11b51df6a3175442d6a9ff85
Author: Vladimir Sitnikov <[email protected]>
AuthorDate: Wed Nov 26 17:27:13 2025 +0500
fix: report generation used wrong paths for the output files
The regression was introduced in
f5518e348199cb362957d473c524b209e7d6a706
"chore: remove the use of commons-io and commons-text"
getNameWithoutExtension returns the file name without the parent path.
---
.../jmeter/report/dashboard/TemplateVisitor.java | 9 +++-
.../jmeter/gui/action/HtmlReportGeneratorTest.kt | 56 ++++++++++++++++++++++
2 files changed, 64 insertions(+), 1 deletion(-)
diff --git
a/src/core/src/main/java/org/apache/jmeter/report/dashboard/TemplateVisitor.java
b/src/core/src/main/java/org/apache/jmeter/report/dashboard/TemplateVisitor.java
index d64205f5e6..bc1c646e1e 100644
---
a/src/core/src/main/java/org/apache/jmeter/report/dashboard/TemplateVisitor.java
+++
b/src/core/src/main/java/org/apache/jmeter/report/dashboard/TemplateVisitor.java
@@ -104,7 +104,14 @@ public class TemplateVisitor extends
SimpleFileVisitor<Path> {
// Process template file
String templatePath = relativePath.toString();
Template template = configuration.getTemplate(templatePath);
- Path newPath =
target.resolve(PathsKt.getNameWithoutExtension(relativePath));
+ Path newPath = target;
+ // getNameWithoutExtension returns the file name without the
parent folder,
+ // so we resolve the parent first and then add the file name
without extension
+ Path newRelativeParent = relativePath.getParent();
+ if (newRelativeParent != null) {
+ newPath = newPath.resolve(newRelativeParent);
+ }
+ newPath =
newPath.resolve(PathsKt.getNameWithoutExtension(relativePath));
try (FileOutputStream stream = new
FileOutputStream(newPath.toString());
Writer writer = new OutputStreamWriter(stream,
StandardCharsets.UTF_8);
BufferedWriter bufferedWriter = new
BufferedWriter(writer)){
diff --git
a/src/dist-check/src/test/kotlin/org/apache/jmeter/gui/action/HtmlReportGeneratorTest.kt
b/src/dist-check/src/test/kotlin/org/apache/jmeter/gui/action/HtmlReportGeneratorTest.kt
index f0740bb0ef..6f65c555dd 100644
---
a/src/dist-check/src/test/kotlin/org/apache/jmeter/gui/action/HtmlReportGeneratorTest.kt
+++
b/src/dist-check/src/test/kotlin/org/apache/jmeter/gui/action/HtmlReportGeneratorTest.kt
@@ -21,6 +21,8 @@ import com.fasterxml.jackson.databind.ObjectMapper
import org.apache.jmeter.junit.JMeterTestCase
import org.apache.jmeter.util.JMeterUtils
import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertFalse
+import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.fail
import org.junit.jupiter.api.io.TempDir
@@ -36,6 +38,22 @@ class HtmlReportGeneratorTest : JMeterTestCase() {
data class CheckArgumentsCase(val csvPath: String, val userPropertiesPath:
String, val outputDirectoryPath: String, val expected: List<String>)
+ /**
+ * Assert that a file exists at the given path relative to a base directory
+ */
+ private fun assertFileExists(baseDir: File, relativePath: String, message:
String? = null) {
+ val file = File(baseDir, relativePath)
+ assertTrue(file.exists()) { message ?: "$relativePath should exist" }
+ }
+
+ /**
+ * Assert that a file does NOT exist at the given path relative to a base
directory
+ */
+ private fun assertFileNotExists(baseDir: File, relativePath: String,
message: String? = null) {
+ val file = File(baseDir, relativePath)
+ assertFalse(file.exists()) { message ?: "$relativePath should NOT
exist" }
+ }
+
companion object {
/**
* Combine the given path parts to one path with the correct path
separator of the current platform.
@@ -141,4 +159,42 @@ class HtmlReportGeneratorTest : JMeterTestCase() {
fail("First result message should contain '$expectedError', but
was '$firstMessage'")
}
}
+
+ @Test
+ fun `report generation creates correct directory structure for HTML and JS
files`() {
+ val htmlReportGenerator = HtmlReportGenerator(
+ combine("testfiles", "HTMLReportTestFile.csv"),
+ combine("user.properties"),
+ testDirectory.toString()
+ )
+ htmlReportGenerator.run()
+
+ // Verify directory structure exists
+ assertFileExists(testDirectory, "content")
+ assertFileExists(testDirectory, "content/pages")
+ assertFileExists(testDirectory, "content/js")
+
+ // Verify HTML pages are in correct location (content/pages/)
+ assertFileExists(testDirectory, "content/pages/OverTime.html")
+ assertFileExists(testDirectory, "content/pages/ResponseTimes.html")
+ assertFileExists(testDirectory, "content/pages/Throughput.html")
+ assertFileExists(testDirectory, "content/pages/CustomsGraphs.html")
+
+ // Verify JavaScript files are in correct location (content/js/)
+ assertFileExists(testDirectory, "content/js/dashboard.js")
+ assertFileExists(testDirectory, "content/js/graph.js")
+ assertFileExists(testDirectory, "content/js/dashboard-commons.js")
+ assertFileExists(testDirectory, "content/js/customGraph.js")
+
+ // Verify files are NOT at root level (catches the bug!)
+ assertFileNotExists(testDirectory, "OverTime.html", "OverTime.html
should NOT be at root level")
+ assertFileNotExists(testDirectory, "ResponseTimes.html",
"ResponseTimes.html should NOT be at root level")
+ assertFileNotExists(testDirectory, "Throughput.html", "Throughput.html
should NOT be at root level")
+ assertFileNotExists(testDirectory, "CustomsGraphs.html",
"CustomsGraphs.html should NOT be at root level")
+ assertFileNotExists(testDirectory, "dashboard.js", "dashboard.js
should NOT be at root level")
+ assertFileNotExists(testDirectory, "graph.js", "graph.js should NOT be
at root level")
+
+ // Verify index.html is at root (this should be correct)
+ assertFileExists(testDirectory, "index.html", "index.html should exist
at root level")
+ }
}