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
2 changes: 1 addition & 1 deletion get_latest_downloaded_file_path/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.testsigma.addons</groupId>
<artifactId>get_latest_downloaded_file_path</artifactId>
<version>1.0.2</version>
<version>1.0.3</version>
<packaging>jar</packaging>

<properties>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.testsigma.addons.web;

import com.testsigma.addons.web.util.Utilities;
import com.testsigma.addons.web.util.UtilitiesFactory;
import com.testsigma.sdk.ApplicationType;
import com.testsigma.sdk.Result;
import com.testsigma.sdk.WebAction;
import com.testsigma.sdk.annotation.Action;
import com.testsigma.sdk.annotation.RunTimeData;
import com.testsigma.sdk.annotation.TestData;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

@EqualsAndHashCode(callSuper = true)
@Data
@Action(actionText = "Get latest downloaded content and store in runtime variable variable-name",
description = "Retrieves the local path of the most recently downloaded file from the browser" +
" (Chrome/Edge) and stores it in a runtime variable.",
applicationType = ApplicationType.WEB)
Comment thread
ManojTestsigma marked this conversation as resolved.
public class GetLatestDownloadedFileName extends WebAction {

@TestData(reference = "content", allowedValues = {"file-name", "file-path", "file-name-with-extension", "file-extension"})
private com.testsigma.sdk.TestData content;

@TestData(reference = "variable-name", isRuntimeVariable = true)
private com.testsigma.sdk.TestData runtimeVariable;

@RunTimeData
private com.testsigma.sdk.RunTimeData runTimeData;

@Override
protected Result execute() throws NoSuchElementException {
Result result = Result.SUCCESS;
Utilities utilities = UtilitiesFactory.create(driver, logger);
String originalWindowHandle = driver.getWindowHandle();
try {
logger.info("Initiated execution");
String contentType = content.getValue().toString().trim().toLowerCase();

String storedValue;
if ("file-path".equals(contentType)) {
// Copy the file locally and return the temp file path
File localFile = utilities.copyFileFromDownloads();
logger.info("Local file path: " + localFile.getAbsolutePath());
storedValue = localFile.getAbsolutePath();
} else {
// For name/extension, read the original file name from the downloads page
// without copying the entire file
((JavascriptExecutor) driver).executeScript("window.open('about:blank','_blank');");
List<String> tabs = new ArrayList<>(driver.getWindowHandles());
driver.switchTo().window(tabs.get(tabs.size() - 1));
try {
if (!utilities.isFileDownloaded()) {
throw new RuntimeException("File is still downloading.");
}
String originalPath = utilities.getDownloadedFileLocalPath();
logger.info("Original downloaded file path: " + originalPath);

int lastSep = Math.max(originalPath.lastIndexOf('/'), originalPath.lastIndexOf('\\'));
String originalFileName = lastSep >= 0 ? originalPath.substring(lastSep + 1) : originalPath;
int dotIndex = originalFileName.lastIndexOf('.');

switch (contentType) {
case "file-name":
storedValue = dotIndex > 0 ? originalFileName.substring(0, dotIndex) : originalFileName;
break;
case "file-name-with-extension":
storedValue = originalFileName;
break;
case "file-extension":
storedValue = dotIndex > 0 ? originalFileName.substring(dotIndex + 1) : "";
break;
default:
storedValue = originalFileName;
break;
}
} finally {
driver.close();
driver.switchTo().window(originalWindowHandle);
}
Comment on lines +56 to +87
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Possible temporary-tab leak on early failure.

The new blank tab is opened on line 56 and the switch happens on line 58, but the try/finally that restores the original window handle and closes the tab only starts at line 59. If executeScript, getWindowHandles, or switchTo().window(...) throws, the temp tab is left open and the driver may be pointed at it, which cascades into the outer catch where no cleanup runs.

Consider moving the tab creation/switch inside the try block (or wrap the whole else-branch in a try/finally that restores originalWindowHandle and closes any extra tabs).

🛠️ Suggested structure
-                ((JavascriptExecutor) driver).executeScript("window.open('about:blank','_blank');");
-                List<String> tabs = new ArrayList<>(driver.getWindowHandles());
-                driver.switchTo().window(tabs.get(tabs.size() - 1));
-                try {
+                try {
+                    ((JavascriptExecutor) driver).executeScript("window.open('about:blank','_blank');");
+                    List<String> tabs = new ArrayList<>(driver.getWindowHandles());
+                    driver.switchTo().window(tabs.get(tabs.size() - 1));
                     if (!utilities.isFileDownloaded()) {
                         throw new RuntimeException("File is still downloading.");
                     }
                     ...
                 } finally {
-                    driver.close();
-                    driver.switchTo().window(originalWindowHandle);
+                    if (!driver.getWindowHandle().equals(originalWindowHandle)) {
+                        driver.close();
+                    }
+                    driver.switchTo().window(originalWindowHandle);
                 }
📝 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.

Suggested change
((JavascriptExecutor) driver).executeScript("window.open('about:blank','_blank');");
List<String> tabs = new ArrayList<>(driver.getWindowHandles());
driver.switchTo().window(tabs.get(tabs.size() - 1));
try {
if (!utilities.isFileDownloaded()) {
throw new RuntimeException("File is still downloading.");
}
String originalPath = utilities.getDownloadedFileLocalPath();
logger.info("Original downloaded file path: " + originalPath);
int lastSep = Math.max(originalPath.lastIndexOf('/'), originalPath.lastIndexOf('\\'));
String originalFileName = lastSep >= 0 ? originalPath.substring(lastSep + 1) : originalPath;
int dotIndex = originalFileName.lastIndexOf('.');
switch (contentType) {
case "file-name":
storedValue = dotIndex > 0 ? originalFileName.substring(0, dotIndex) : originalFileName;
break;
case "file-name-with-extension":
storedValue = originalFileName;
break;
case "file-extension":
storedValue = dotIndex > 0 ? originalFileName.substring(dotIndex + 1) : "";
break;
default:
storedValue = originalFileName;
break;
}
} finally {
driver.close();
driver.switchTo().window(originalWindowHandle);
}
try {
((JavascriptExecutor) driver).executeScript("window.open('about:blank','_blank');");
List<String> tabs = new ArrayList<>(driver.getWindowHandles());
driver.switchTo().window(tabs.get(tabs.size() - 1));
if (!utilities.isFileDownloaded()) {
throw new RuntimeException("File is still downloading.");
}
String originalPath = utilities.getDownloadedFileLocalPath();
logger.info("Original downloaded file path: " + originalPath);
int lastSep = Math.max(originalPath.lastIndexOf('/'), originalPath.lastIndexOf('\\'));
String originalFileName = lastSep >= 0 ? originalPath.substring(lastSep + 1) : originalPath;
int dotIndex = originalFileName.lastIndexOf('.');
switch (contentType) {
case "file-name":
storedValue = dotIndex > 0 ? originalFileName.substring(0, dotIndex) : originalFileName;
break;
case "file-name-with-extension":
storedValue = originalFileName;
break;
case "file-extension":
storedValue = dotIndex > 0 ? originalFileName.substring(dotIndex + 1) : "";
break;
default:
storedValue = originalFileName;
break;
}
} finally {
if (!driver.getWindowHandle().equals(originalWindowHandle)) {
driver.close();
}
driver.switchTo().window(originalWindowHandle);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@get_latest_downloaded_file_path/src/main/java/com/testsigma/addons/web/GetLatestDownloadedFileName.java`
around lines 56 - 87, The blank tab creation and switch
(JavascriptExecutor.executeScript, driver.getWindowHandles,
driver.switchTo().window) occur before the try/finally that closes the tab, so
if any of those calls throw the temp tab can leak; move the tab-open and switch
logic inside the existing try block (or expand the try to start before
executeScript) in GetLatestDownloadedFileName so that the finally always runs
and always executes driver.close() and
driver.switchTo().window(originalWindowHandle); ensure you still capture
originalWindowHandle before opening the new tab and keep
utilities.isFileDownloaded(), utilities.getDownloadedFileLocalPath(), and the
contentType switch unchanged.

}

runTimeData.setKey(runtimeVariable.getValue().toString());
runTimeData.setValue(storedValue);
setSuccessMessage("Successfully stored the latest downloaded " + contentType + " in the runtime variable. "
+ runtimeVariable.getValue().toString() + " = " + storedValue);
} catch (Exception e) {
logger.info("Exception Occurred: " + ExceptionUtils.getStackTrace(e));
setErrorMessage("Exception Occurred while extracting the latest downloaded file content. Exception: "
+ ExceptionUtils.getMessage(e));
result = Result.FAILED;
}
return result;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.testsigma.addons.web;

import com.testsigma.addons.web.util.Utilities;
import com.testsigma.addons.web.util.UtilitiesFactory;
import com.testsigma.sdk.Result;
import com.testsigma.sdk.WebAction;
import com.testsigma.sdk.ApplicationType;
import com.testsigma.sdk.annotation.Action;
import com.testsigma.sdk.annotation.TestData;
import lombok.Data;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.openqa.selenium.NoSuchElementException;

import java.io.File;
import java.nio.file.Files;

@Data
@Action(actionText = "Verify if the latest downloaded file type is expected-file-type",
description = "Verifies that the most recently downloaded file has the expected file type/extension",
applicationType = ApplicationType.WEB,
useCustomScreenshot = false)
public class VerifyIfTheLatestFileType extends WebAction {

@TestData(reference = "expected-file-type", allowedValues = {"pdf", "png", "jpg", "jpeg", "csv", "zip", "xlsx", "docx", "txt"})
private com.testsigma.sdk.TestData testData;

@Override
public Result execute() throws NoSuchElementException {
logger.info("Initiating execution");
Result result = Result.SUCCESS;

String currentWindowHandle = driver.getWindowHandle();
try {
String expectedFileType = testData.getValue().toString().trim().toLowerCase().replaceAll("^\\.", "");
logger.info("Expected file type: " + expectedFileType);

String expectedMimeType;
switch (expectedFileType) {
case "pdf": expectedMimeType = "application/pdf"; break;
case "png": expectedMimeType = "image/png"; break;
case "jpg":
case "jpeg": expectedMimeType = "image/jpeg"; break;
case "csv": expectedMimeType = "text/csv"; break;
case "zip": expectedMimeType = "application/zip"; break;
case "xlsx": expectedMimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; break;
case "docx": expectedMimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; break;
Comment thread
ManojTestsigma marked this conversation as resolved.
case "txt": expectedMimeType = "text/plain"; break;
default:
setErrorMessage("Unsupported file type: '" + expectedFileType + "'. Supported types: pdf, png, jpg, jpeg, csv, zip, xlsx, docx, txt");
return Result.FAILED;
}
logger.info("Expected MIME type: " + expectedMimeType);

Utilities utilities = UtilitiesFactory.create(driver, logger);
File localFile = utilities.copyFileFromDownloads();
logger.info("Local temp file: " + localFile.getAbsolutePath());

String actualFileType;
try {
actualFileType = Files.probeContentType(localFile.toPath());
} finally {
localFile.delete();
}

if (actualFileType == null) {
setErrorMessage("Could not determine file type of downloaded file: " + localFile.getName());
return Result.FAILED;
}
logger.info("Actual file type: " + actualFileType);

if (actualFileType.equals(expectedMimeType)) {
setSuccessMessage("Verified: the latest downloaded file type is '" + expectedFileType + "' as expected.");
} else {
setErrorMessage("File type mismatch: expected '" + expectedFileType + "' but found '" + actualFileType + "'.");
result = Result.FAILED;
}
} catch (Exception e) {
logger.info("Error while verifying file type: " + ExceptionUtils.getStackTrace(e));
setErrorMessage("Error while verifying file type: " + e.getMessage());
result = Result.FAILED;
} finally {
driver.switchTo().window(currentWindowHandle);
}

return result;
}
}