Skip to content

Conversation

@akhil-testsigma
Copy link
Contributor

@akhil-testsigma akhil-testsigma commented Jan 16, 2026

Publish this addon as public (EU Region)

Addon Name: Pdf Actions 21
Jarvis Link: https://jarvis-eu.testsigma.com/ui/tenants/66076/addons
Jira : https://testsigma.atlassian.net/browse/CUS-10113
Migrated the addon to EU Region

Summary by CodeRabbit

  • New Features

    • Added comprehensive PDF text extraction and verification capabilities, including support for character/word extraction around specific text locations, page-range specific text search, and authenticated PDF access.
  • Chores

    • Added configuration for API integration.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

Introduces a new Maven module for PDF manipulation actions in the Testsigma automation framework. Includes a utility class for PDF document retrieval from URLs, nine WebAction classes for PDF content verification and text extraction with optional HTTP authentication support, Maven build configuration, and SDK properties.

Changes

Cohort / File(s) Summary
Project Configuration
pdf_actions_21/pom.xml, pdf_actions_21/src/main/resources/testsigma-sdk.properties
Maven project descriptor defining Java 11 compatibility, dependencies (PDFBox, Selenium, Appium, Jackson, TestNG, JUnit 5), Maven Shade Plugin for packaging, and SDK API key property.
PDF Utility
pdf_actions_21/src/main/java/com/testsigma/addons/util/PDFUtils.java
Public utility class providing static method to retrieve and load PDF documents from URLs via HttpClient, with temporary file handling and PDFBox integration.
PDF Text Verification Actions
pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextpdf.java, ContainsTextPDFWithAuth.java, VerifypdfContent.java, VerifyTextinparticularpage.java
WebAction classes that verify presence of specified text in PDF documents, with one supporting HTTP Basic authentication and another supporting page range specification.
PDF Content Reading Actions
pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadpdfContent.java, ReadPdfContentWithAuth.java
WebAction classes that extract and store full PDF text content to runtime variables, with one supporting HTTP Basic authentication.
PDF Character/Word Extraction Actions
pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofCharaftertext.java, NoofCharbeforetext.java, NoofwordsAftertext.java, NoofwordsBeforetext.java
WebAction classes that extract and store specified counts of characters or words before/after target text patterns from PDFs to runtime variables.

Suggested reviewers

  • Ganesh-Testsigma
  • vigneshtestsigma

Poem

🐰 A PDF module hops into view,
With actions to read and to verify too,
Text extraction magic, authentication's true,
Nine ways to process, both before and after—
Testsigma's toolkit grows with PDF laughter! 📄✨

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: migrating the PDF Actions 21 addon to the EU Region, which aligns with the PR objective and the addition of the API key in testsigma-sdk.properties.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 18

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🤖 Fix all issues with AI agents
In `@pdf_actions_21/pom.xml`:
- Around line 36-46: Update the pre-release JUnit and outdated TestNG entries:
change org.junit.jupiter:artifactId junit-jupiter-api to use the stable version
5.14.2 (replace ${junit.jupiter.version} or set that property to 5.14.2) and
update org.testng:testng from 6.14.3 to 7.9.0; also add a <scope>test</scope> to
the org.testng:testng dependency so TestNG is not packaged in the production
artifact.

In `@pdf_actions_21/src/main/java/com/testsigma/addons/util/PDFUtils.java`:
- Around line 17-44: getPDDocument currently returns an open PDDocument that
callers must close, creating a resource leak; either document this contract
clearly and update all callsites (e.g., ContainsTextpdf, NoofCharaftertext) to
call close() in a finally/try-with-resources, or refactor getPDDocument into a
variant that accepts a consumer/function (e.g., getPDDocument(String url,
Consumer<PDDocument> consumer) or <T> T withPDDocument(String url,
Function<PDDocument,T> fn)) that loads the PDDocument, invokes the callback, and
always closes the document in a finally block; update all callers to use the new
API so the PDDocument is closed inside the utility.
- Around line 23-36: Check HTTP response status in the block that handles
client.send (response variable) before copying response.body() to tempFilePath:
if response.statusCode() is not 2xx, throw a clear Exception (include status
code and response headers/body if available) and do not attempt Files.copy;
replace the System.out.println("Temporary file created: " + tempFilePath) call
with a proper logger call (add a logger field on PDFUtils, e.g., private static
final Logger logger = LoggerFactory.getLogger(PDFUtils.class) or
java.util.logging.Logger) and use logger.info/logger.error for success and error
messages respectively.

In `@pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextpdf.java`:
- Around line 40-43: In ContainsTextpdf inside the else branch (where
setErrorMessage and logger.warn are called), stop logging the full PDF text
(sb.toString()); instead log safe info such as a truncated snippet (e.g., first
100 characters) or non-sensitive metadata or a hash of sb to avoid PII
exposure—modify the logger.warn call to include ERROR_MESSAGE,
testData.getValue(), and a truncated/snipped version or hash of sb (and
optionally indicate truncation) while leaving setErrorMessage unchanged.
- Around line 33-35: The PDDocument returned by PDFUtils.getPDDocument in
ContainsTextpdf is never closed, causing a resource leak; update the code in the
try block where PDDocument doc is obtained (from PDFUtils.getPDDocument) and
text extracted via new PDFTextStripper().getText(doc) to ensure the document is
closed — either use a try-with-resources around PDDocument doc or close doc in a
finally block after extracting text to release file handles and memory.

In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextPDFWithAuth.java`:
- Around line 37-43: The current use of Authenticator.setDefault(...) in
ContainsTextPDFWithAuth (overriding getPasswordAuthentication and using
username/password) sets a JVM-wide authenticator which is not thread-safe;
change to per-request credentials instead — either build an Authorization header
with Basic <base64(username:password)> and set it on the HttpURLConnection used
to fetch the PDF, or construct a java.net.http.HttpClient with a per-client
Authenticator and use that client for the request; remove the global
Authenticator.setDefault call and ensure username.getValue() and
password.getValue() are encoded/supplied only for the specific request.
- Around line 48-61: The PDDocument returned by PDFUtils.getPDDocument in
ContainsTextPDFWithAuth is never closed and you should also remove the TestNG
assertion; wrap PDDocument doc in a try-with-resources (or ensure doc.close() in
finally) so the stream is always closed, then replace
Assert.assertTrue(sb.toString().contains((CharSequence) testData.getValue()))
with a conditional check (e.g., if contains then setSuccessMessage and return
Result.SUCCESS else setErrorMessage and return Result.FAILED) so production
logic controls the Result; keep the existing logging and error handling inside
the catch but ensure you don’t rely on assertions for flow control.

In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofCharaftertext.java`:
- Around line 64-68: In NoofCharaftertext catch block, avoid calling
e.getCause().toString() directly because getCause() may be null; update the
catch to compute a safe cause string (e.g., if e.getCause() != null use
e.getCause().toString() otherwise use e.toString() or
ExceptionUtils.getMessage(e)) and pass that safe string into
setErrorMessage(ERROR_MESSAGE + " Cause of Exception:" + safeCause); keep the
existing logger.debug call and return Result.FAILED as before.
- Around line 43-45: The PDDocument returned by PDFUtils.getPDDocument() is not
closed; wrap its acquisition in a try-with-resources to ensure it is closed
(e.g., replace the current try block that declares PDDocument doc with try
(PDDocument doc = PDFUtils.getPDDocument(driver.getCurrentUrl())) {
sb.append(new PDFTextStripper().getText(doc)); } so PDFTextStripper reads from a
managed resource and no explicit close is needed. Update any surrounding
exception handling accordingly in the NoofCharaftertext class/method.
- Around line 43-55: In NoofCharaftertext (around the block using PDDocument,
hj, indexofword, sum, noofchar, list2) add bounds validation: check that
indexofword != -1 after calling hj.indexOf(testData2.getValue().toString()) and
if it is -1 handle gracefully (throw a descriptive exception or return an
empty/failed result); then compute the maximum available chars = hj.length() -
(sum) and ensure noofchar does not exceed that (adjust noofchar or fail with a
clear message) before entering the for loop that uses hj.charAt(sum + i); this
prevents StringIndexOutOfBoundsException and ensures predictable behavior when
the target text is missing or not enough characters remain.

In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofCharbeforetext.java`:
- Around line 43-69: PDDocument obtained via PDFUtils.getPDDocument(...) is
never closed and you don't validate the index/length before calling charAt, so
wrap PDDocument usage in a try-with-resources (or explicitly close doc) around
the calls that use new PDFTextStripper(), then check indextofword =
hj.indexOf(...) for -1 and handle it (setErrorMessage and return Result.FAILED);
also validate that indextofword >= postionofdesiredchar before the for-loop
(otherwise handle as error) to avoid negative charAt(index) access; update
runTimeData only on success. Reference: PDDocument, PDFUtils.getPDDocument, hj,
indextofword, postionofdesiredchar, charAt, runTimeData.

In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofwordsAftertext.java`:
- Around line 44-66: Close the PDDocument returned by PDFUtils.getPDDocument
using a try-with-resources (or ensure close in finally) to avoid the resource
leak; validate that list.indexOf(testData2.getValue()) returns >= 0 before using
it and compute available words (ensure a + i < list.size()) so list.get(...)
cannot throw IndexOutOfBoundsException when building list2; also
validate/parsesafe testData1.getValue() into an int (catch
NumberFormatException) and in the catch block avoid calling
e.getCause().toString() — use e.getMessage() or ExceptionUtils.getStackTrace(e)
safely when setting setErrorMessage/runTimeData to prevent NPE. Ensure these
checks are applied around PDDocument, new PDFTextStripper().getText(doc), the
loop that builds list2, and the catch block referenced in this diff.

In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofwordsBeforetext.java`:
- Around line 49-57: In NoofwordsBeforetext, guard the code that builds list2:
check the target index 'a' returned by list.indexOf(testData2.getValue()) for -1
and handle it (throw a clear error or return empty/result accordingly), and
ensure the range used when computing a - i cannot go negative (e.g., compute
aStart = Math.max(0, a - wordcount) and iterate from aStart up to a-1 or adjust
wordcount downward); update the logic around variables list, a, wordcount and
list2 to avoid IndexOutOfBoundsException and provide a clear failure path when
the target is missing or has insufficient preceding words.

In `@pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadpdfContent.java`:
- Around line 43-55: The PDDocument obtained via PDFUtils.getPDDocument is not
closed and the exception handler calls e.getCause().toString() which can NPE;
change the PDDocument usage in the method (where PDFUtils.getPDDocument,
PDDocument and PDFTextStripper are used) to a try-with-resources block so the
PDDocument is automatically closed, populate runTimeData and call
setSuccessMessage inside that block, and update the catch block (where logger
and setErrorMessage are used) to avoid e.getCause().toString() by checking if
e.getCause() is null and using e.getMessage() or e.toString() (and include
ExceptionUtils.getStackTrace(e) in the log) when building the error message.

In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadPdfContentWithAuth.java`:
- Around line 59-66: The PDDocument obtained via PDFUtils.getPDDocument is never
closed, risking resource leaks; wrap the PDDocument usage in a
try-with-resources (or explicitly close in finally) where you call
PDFUtils.getPDDocument() and create the PDFTextStripper, then read text and
populate runTimeData (the runTimeData.setValue and setKey calls) and call
setSuccessMessage using the extracted st.trim() and testData.getValue(),
ensuring PDDocument is closed even on exceptions; modify the block around
PDFUtils.getPDDocument, PDFTextStripper, runTimeData, and setSuccessMessage
accordingly.

In `@pdf_actions_21/src/main/java/com/testsigma/addons/web/VerifypdfContent.java`:
- Around line 40-41: The code in VerifypdfContent calls
PDFUtils.getPDDocument(url) and uses new PDFTextStripper().getText(doc) without
closing the PDDocument; wrap the PDDocument creation in a try-with-resources
(try (PDDocument doc = PDFUtils.getPDDocument(url)) { String st = new
PDFTextStripper().getText(doc); ... }) so the PDDocument is always closed and
resources are not leaked; keep usage of PDFTextStripper inside the try block and
propagate or handle exceptions as needed.

In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/VerifyTextinparticularpage.java`:
- Around line 36-58: PDDocument returned by PDFUtils.getPDDocument(...) is never
closed and the catch block calls e.getCause().toString() which may NPE; update
VerifyTextinparticularpage to use a try-with-resources (or ensure a finally
block) to close the PDDocument (the local variable doc) after using
PDFTextStripper, and replace e.getCause().toString() with a null-safe expression
(e.g., check e.getCause() != null ? e.getCause().toString() : e.toString()) when
building the error message so no NPE occurs in the catch.

In `@pdf_actions_21/src/main/resources/testsigma-sdk.properties`:
- Line 1: Remove the hardcoded JWT value assigned to testsigma-sdk.api.key in
testsigma-sdk.properties and replace it with a reference to an environment
variable (e.g., use the placeholder form for TESTSIGMA_API_KEY) or move the
entry into a template file; create testsigma-sdk.properties.template containing
testsigma-sdk.api.key placeholder and add the real testsigma-sdk.properties to
.gitignore so secrets are not committed, then rotate the exposed API key
immediately. Ensure you update any code that reads testsigma-sdk.api.key to fall
back to the TESTSIGMA_API_KEY env var if present.
🟡 Minor comments (4)
pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextpdf.java-15-17 (1)

15-17: Misleading action description.

The description states "stores the extracted text into a run time variable" but the action only verifies text presence and doesn't use @RunTimeData. Consider updating the description to match the actual behavior.

Proposed fix
 `@Action`(actionText = "Verify if the pdf contains text test_data",
-        description = "Extracts the text from the PDF and stores the extracted text into a run time variable",
+        description = "Verifies whether the PDF content contains the specified text",
         applicationType = ApplicationType.WEB)
pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadpdfContent.java-35-42 (1)

35-42: Weak PDF URL detection.

url.contains(".pdf") is unreliable — URLs may have query parameters (e.g., file.pdf?token=abc), mixed case extensions, or no extension at all. Consider checking the Content-Type header or handling this more gracefully.

Suggested improvement
-        if (url.contains(".pdf")) {
-            setSuccessMessage("pdf file detected");
-            System.out.println("PDF detected");
+        if (url.toLowerCase().contains(".pdf")) {
+            logger.info("PDF file detected");
         } else {
-            setErrorMessage("Not a pdf file");
-            System.out.println("PDF not detected");
-            return Result.FAILED;
+            logger.warn("URL may not be a PDF file: " + url);
+            // Consider proceeding anyway and letting PDFBox handle validation
         }
pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofwordsBeforetext.java-68-70 (1)

68-70: Avoid NullPointerException in the error path.

e.getCause() can be null; calling .toString() can throw in the catch block. Use a null-safe message.

🛠️ Suggested fix
-            setErrorMessage(ERROR_MESSAGE+ "" + "Cause of Exception:" + e.getCause().toString());
+            String cause = String.valueOf(e.getCause());
+            setErrorMessage(ERROR_MESSAGE + " Cause of Exception: " + cause);
pdf_actions_21/src/main/java/com/testsigma/addons/web/VerifypdfContent.java-51-54 (1)

51-54: Make error handling null-safe.

e.getCause() can be null; calling .toString() will throw and mask the original error.

🛠️ Suggested fix
-            setErrorMessage("Cause of Exception:" + e.getCause().toString());
+            setErrorMessage("Cause of Exception: " + String.valueOf(e.getCause()));
🧹 Nitpick comments (6)
pdf_actions_21/src/main/java/com/testsigma/addons/util/PDFUtils.java (1)

17-21: Consider adding HTTP client timeout to prevent indefinite hangs.

The HttpClient is created without timeouts, which could cause the action to hang indefinitely if the server is unresponsive.

Proposed fix
+import java.time.Duration;
+
     public static PDDocument getPDDocument(String urlString) throws Exception {
-        HttpClient client = HttpClient.newHttpClient();
+        HttpClient client = HttpClient.newBuilder()
+                .connectTimeout(Duration.ofSeconds(30))
+                .build();
         HttpRequest request = HttpRequest.newBuilder()
                 .uri(new URI(urlString))
+                .timeout(Duration.ofSeconds(60))
                 .build();
pdf_actions_21/src/main/java/com/testsigma/addons/web/VerifyTextinparticularpage.java (1)

22-22: Unused field result.

The Result result field is declared but never used. Consider removing it.

pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofwordsAftertext.java (1)

60-60: Replace System.out.println with logger.

Use the inherited logger instead of System.out.println for consistent logging.

pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextPDFWithAuth.java (1)

13-13: Remove unused org.testng.Assert import.

If adopting the conditional logic approach suggested above, this import becomes unnecessary.

pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadpdfContent.java (1)

37-40: Replace System.out.println with logger.

Use the inherited logger for consistent logging instead of System.out.println.

pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadPdfContentWithAuth.java (1)

63-66: Avoid embedding full PDF content in the success message.

The success message can become extremely large and may leak sensitive PDF contents in logs/UI. Consider truncating the preview or omitting the content entirely.

💡 Example adjustment
-                setSuccessMessage("The Stored content in PDF is : " + st.trim() + "and stored in the runtime variable :"
-                        + testData.getValue());
+                String trimmed = st.trim();
+                String preview = trimmed.length() > 200 ? trimmed.substring(0, 200) + "…" : trimmed;
+                setSuccessMessage("Stored PDF content in runtime variable: " + testData.getValue()
+                        + ". Preview: " + preview);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6bebe87 and 1ca084a.

📒 Files selected for processing (13)
  • pdf_actions_21/pom.xml
  • pdf_actions_21/src/main/java/com/testsigma/addons/util/PDFUtils.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextPDFWithAuth.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextpdf.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofCharaftertext.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofCharbeforetext.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofwordsAftertext.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofwordsBeforetext.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadPdfContentWithAuth.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadpdfContent.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/VerifyTextinparticularpage.java
  • pdf_actions_21/src/main/java/com/testsigma/addons/web/VerifypdfContent.java
  • pdf_actions_21/src/main/resources/testsigma-sdk.properties
🔇 Additional comments (4)
pdf_actions_21/pom.xml (2)

69-73: PDFBox dependency looks appropriate.

PDFBox 3.0.1 is a suitable choice for PDF manipulation. The dependency configuration is correct.


47-52: No action required. Selenium version 4.33.0 is available and stable on Maven Central Repository. (Latest version is 4.39.0 if updating is desired.)

Likely an incorrect or invalid review comment.

pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadPdfContentWithAuth.java (1)

37-43: Please provide the review comment (within <review_comment> tags) that needs to be rewritten.

pdf_actions_21/src/main/java/com/testsigma/addons/web/NoofwordsBeforetext.java (1)

45-46: I need the review comment that requires rewriting. Please provide the review comment within <review_comment> tags, along with any relevant context about the code being reviewed (file path, code snippet, etc.).

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +36 to +46
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
</dependency>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

latest stable JUnit Jupiter version 2025 2026

💡 Result:

Latest stable JUnit Jupiter: junit-jupiter 5.14.2 (released January 6, 2026). [1]

Note: JUnit 6 (unified numbering) also has stable releases (e.g., 6.0.1). [2]

Sources:

  • JUnit release notes — 5.14.2 (Jan 6, 2026). [1]
  • JUnit release notes — 6.0.1 (Oct 31, 2025). [2]

🌐 Web query:

TestNG latest stable version 2025 2026

💡 Result:

The latest stable TestNG release (as listed on the official TestNG site) is 7.9.0 (documented on the download/current-release page). [1][2]

Sources:

  • TestNG official documentation / download (Current release: 7.9.0). [1]
  • TestNG main site (Current Release section showing 7.9.0). [2]

🌐 Web query:

Selenium WebDriver version 4.33.0 valid

💡 Result:

Yes — Selenium WebDriver 4.33.0 is a valid released version (published May 23, 2025). [1][2]

Sources:

  • Selenium GitHub releases (v4.33.0). [1]
  • Maven Central / Selenium artifacts (4.33.0 published May 23, 2025). [2]

Update to stable dependency versions and add proper scopes.

  • junit-jupiter-api:5.8.0-M1 is a milestone (pre-release) version. Use the latest stable release 5.14.2.
  • testng:6.14.3 is outdated; TestNG 7.9.0 is the current stable version.
  • TestNG is missing <scope>test</scope>, which means it will be bundled into the shaded JAR unnecessarily.
🤖 Prompt for AI Agents
In `@pdf_actions_21/pom.xml` around lines 36 - 46, Update the pre-release JUnit
and outdated TestNG entries: change org.junit.jupiter:artifactId
junit-jupiter-api to use the stable version 5.14.2 (replace
${junit.jupiter.version} or set that property to 5.14.2) and update
org.testng:testng from 6.14.3 to 7.9.0; also add a <scope>test</scope> to the
org.testng:testng dependency so TestNG is not packaged in the production
artifact.

Comment on lines +17 to +44
public static PDDocument getPDDocument(String urlString) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI(urlString))
.build();

// Send request and get response as InputStream
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());

// Create a temporary file to store the PDF
Path tempFilePath = Files.createTempFile("tempfile-", ".pdf");
tempFilePath.toFile().deleteOnExit(); // Delete temp file on JVM exit

// Copy the response InputStream to the temporary file
try (InputStream is = response.body()) {
Files.copy(is, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Temporary file created: " + tempFilePath);
} catch (Exception e) {
throw new Exception("Error while copying the PDF from URL to temporary file", e);
}
// Load PDF from the temporary file path
try {
return Loader.loadPDF(tempFilePath.toFile());
} catch (Exception e) {
throw new Exception("Error while loading the PDF document", e);
}

}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

PDDocument resource leak - callers must close the returned document.

The method returns an open PDDocument that the caller is responsible for closing. However, there's no documentation indicating this, and none of the calling actions (e.g., ContainsTextpdf, NoofCharaftertext) appear to close the document after use.

Consider either:

  1. Documenting the contract and ensuring all callers close the document
  2. Refactoring to accept a callback/consumer pattern that handles cleanup internally
Example: Document the contract
+    /**
+     * Loads a PDF document from the given URL.
+     * <p><b>Important:</b> The caller is responsible for closing the returned PDDocument.</p>
+     *
+     * `@param` urlString the URL to fetch the PDF from
+     * `@return` the loaded PDDocument (must be closed by caller)
+     * `@throws` Exception if fetching or loading fails
+     */
     public static PDDocument getPDDocument(String urlString) throws Exception {
🤖 Prompt for AI Agents
In `@pdf_actions_21/src/main/java/com/testsigma/addons/util/PDFUtils.java` around
lines 17 - 44, getPDDocument currently returns an open PDDocument that callers
must close, creating a resource leak; either document this contract clearly and
update all callsites (e.g., ContainsTextpdf, NoofCharaftertext) to call close()
in a finally/try-with-resources, or refactor getPDDocument into a variant that
accepts a consumer/function (e.g., getPDDocument(String url,
Consumer<PDDocument> consumer) or <T> T withPDDocument(String url,
Function<PDDocument,T> fn)) that loads the PDDocument, invokes the callback, and
always closes the document in a finally block; update all callers to use the new
API so the PDDocument is closed inside the utility.

Comment on lines +23 to +36
// Send request and get response as InputStream
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());

// Create a temporary file to store the PDF
Path tempFilePath = Files.createTempFile("tempfile-", ".pdf");
tempFilePath.toFile().deleteOnExit(); // Delete temp file on JVM exit

// Copy the response InputStream to the temporary file
try (InputStream is = response.body()) {
Files.copy(is, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Temporary file created: " + tempFilePath);
} catch (Exception e) {
throw new Exception("Error while copying the PDF from URL to temporary file", e);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add HTTP response status validation and replace System.out with logger.

The code proceeds to process the response without checking the HTTP status code. A 404, 500, or other error response will result in a cryptic failure when attempting to parse an invalid PDF.

Additionally, System.out.println should be replaced with a proper logging framework.

Proposed fix
         // Send request and get response as InputStream
         HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
 
+        // Validate HTTP response status
+        if (response.statusCode() < 200 || response.statusCode() >= 300) {
+            throw new Exception("Failed to fetch PDF. HTTP status: " + response.statusCode());
+        }
+
         // Create a temporary file to store the PDF
         Path tempFilePath = Files.createTempFile("tempfile-", ".pdf");
         tempFilePath.toFile().deleteOnExit(); // Delete temp file on JVM exit
 
         // Copy the response InputStream to the temporary file
         try (InputStream is = response.body()) {
             Files.copy(is, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
-            System.out.println("Temporary file created: " + tempFilePath);
+            // Consider using a logger: logger.debug("Temporary file created: {}", tempFilePath);
         } catch (Exception e) {
             throw new Exception("Error while copying the PDF from URL to temporary file", e);
         }
📝 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
// Send request and get response as InputStream
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
// Create a temporary file to store the PDF
Path tempFilePath = Files.createTempFile("tempfile-", ".pdf");
tempFilePath.toFile().deleteOnExit(); // Delete temp file on JVM exit
// Copy the response InputStream to the temporary file
try (InputStream is = response.body()) {
Files.copy(is, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Temporary file created: " + tempFilePath);
} catch (Exception e) {
throw new Exception("Error while copying the PDF from URL to temporary file", e);
}
// Send request and get response as InputStream
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
// Validate HTTP response status
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new Exception("Failed to fetch PDF. HTTP status: " + response.statusCode());
}
// Create a temporary file to store the PDF
Path tempFilePath = Files.createTempFile("tempfile-", ".pdf");
tempFilePath.toFile().deleteOnExit(); // Delete temp file on JVM exit
// Copy the response InputStream to the temporary file
try (InputStream is = response.body()) {
Files.copy(is, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
// Consider using a logger: logger.debug("Temporary file created: {}", tempFilePath);
} catch (Exception e) {
throw new Exception("Error while copying the PDF from URL to temporary file", e);
}
🤖 Prompt for AI Agents
In `@pdf_actions_21/src/main/java/com/testsigma/addons/util/PDFUtils.java` around
lines 23 - 36, Check HTTP response status in the block that handles client.send
(response variable) before copying response.body() to tempFilePath: if
response.statusCode() is not 2xx, throw a clear Exception (include status code
and response headers/body if available) and do not attempt Files.copy; replace
the System.out.println("Temporary file created: " + tempFilePath) call with a
proper logger call (add a logger field on PDFUtils, e.g., private static final
Logger logger = LoggerFactory.getLogger(PDFUtils.class) or
java.util.logging.Logger) and use logger.info/logger.error for success and error
messages respectively.

Comment on lines +33 to +35
try {
PDDocument doc = PDFUtils.getPDDocument(driver.getCurrentUrl());
sb.append(new PDFTextStripper().getText(doc));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

PDDocument resource leak - document is never closed.

Same issue as other actions: the PDDocument must be closed after use to release file handles and memory.

Proposed fix
-            PDDocument doc = PDFUtils.getPDDocument(driver.getCurrentUrl());
-            sb.append(new PDFTextStripper().getText(doc));
+            try (PDDocument doc = PDFUtils.getPDDocument(driver.getCurrentUrl())) {
+                sb.append(new PDFTextStripper().getText(doc));
+            }
             if (sb.toString().contains((CharSequence) testData.getValue())) {
🤖 Prompt for AI Agents
In `@pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextpdf.java`
around lines 33 - 35, The PDDocument returned by PDFUtils.getPDDocument in
ContainsTextpdf is never closed, causing a resource leak; update the code in the
try block where PDDocument doc is obtained (from PDFUtils.getPDDocument) and
text extracted via new PDFTextStripper().getText(doc) to ensure the document is
closed — either use a try-with-resources around PDDocument doc or close doc in a
finally block after extracting text to release file handles and memory.

Comment on lines +40 to +43
} else {
setErrorMessage(ERROR_MESSAGE + " " + testData.getValue());
logger.warn(ERROR_MESSAGE + " " + testData.getValue() +":" +sb.toString());
return Result.FAILED;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid logging full PDF content - potential sensitive data exposure.

Logging the entire PDF content (sb.toString()) in the warning message could expose sensitive or personal information (PII) to logs. Consider logging only metadata or a truncated snippet.

Proposed fix
             } else {
             	setErrorMessage(ERROR_MESSAGE + " " + testData.getValue());
-            	logger.warn(ERROR_MESSAGE + " " + testData.getValue() +":" +sb.toString());
+            	logger.warn(ERROR_MESSAGE + " " + testData.getValue() + " (PDF length: " + sb.length() + " chars)");
                 return Result.FAILED;
             }
🤖 Prompt for AI Agents
In `@pdf_actions_21/src/main/java/com/testsigma/addons/web/ContainsTextpdf.java`
around lines 40 - 43, In ContainsTextpdf inside the else branch (where
setErrorMessage and logger.warn are called), stop logging the full PDF text
(sb.toString()); instead log safe info such as a truncated snippet (e.g., first
100 characters) or non-sensitive metadata or a hash of sb to avoid PII
exposure—modify the logger.warn call to include ERROR_MESSAGE,
testData.getValue(), and a truncated/snipped version or hash of sb (and
optionally indicate truncation) while leaving setErrorMessage unchanged.

Comment on lines +43 to +55
try {
PDDocument doc = PDFUtils.getPDDocument(url);
String st=new PDFTextStripper().getText(doc);
//sb.append(new PDFTextStripper().getText(doc));
runTimeData = new com.testsigma.sdk.RunTimeData();
runTimeData.setValue(st.trim());
runTimeData.setKey(testData.getValue().toString());
setSuccessMessage("The Stored content in PDF is : " + st.trim() + "and stored in the runtime variable :" + testData.getValue());
} catch (Exception e) {
logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
setErrorMessage("Cause of Exception:" + e.getCause().toString());
return Result.FAILED;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Resource leak and potential NPE in exception handler.

  1. PDDocument is not closed — causes resource leak. Use try-with-resources.
  2. e.getCause() can return null, causing NPE at line 53.
Proposed fix
         try {
-            PDDocument doc = PDFUtils.getPDDocument(url);
-            String st=new PDFTextStripper().getText(doc);
-            //sb.append(new PDFTextStripper().getText(doc));
-            runTimeData = new com.testsigma.sdk.RunTimeData();
-            runTimeData.setValue(st.trim());
-            runTimeData.setKey(testData.getValue().toString());
-            setSuccessMessage("The Stored content in PDF is : " + st.trim() + "and stored in the runtime variable :" + testData.getValue());
+            try (PDDocument doc = PDFUtils.getPDDocument(url)) {
+                String st = new PDFTextStripper().getText(doc);
+                runTimeData = new com.testsigma.sdk.RunTimeData();
+                runTimeData.setValue(st.trim());
+                runTimeData.setKey(testData.getValue().toString());
+                setSuccessMessage("The Stored content in PDF is : " + st.trim() + " and stored in the runtime variable: " + testData.getValue());
+            }
         } catch (Exception e) {
             logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
-            setErrorMessage("Cause of Exception:" + e.getCause().toString());
+            setErrorMessage("Cause of Exception: " + ExceptionUtils.getRootCauseMessage(e));
             return Result.FAILED;
         }
📝 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
try {
PDDocument doc = PDFUtils.getPDDocument(url);
String st=new PDFTextStripper().getText(doc);
//sb.append(new PDFTextStripper().getText(doc));
runTimeData = new com.testsigma.sdk.RunTimeData();
runTimeData.setValue(st.trim());
runTimeData.setKey(testData.getValue().toString());
setSuccessMessage("The Stored content in PDF is : " + st.trim() + "and stored in the runtime variable :" + testData.getValue());
} catch (Exception e) {
logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
setErrorMessage("Cause of Exception:" + e.getCause().toString());
return Result.FAILED;
}
try {
try (PDDocument doc = PDFUtils.getPDDocument(url)) {
String st = new PDFTextStripper().getText(doc);
runTimeData = new com.testsigma.sdk.RunTimeData();
runTimeData.setValue(st.trim());
runTimeData.setKey(testData.getValue().toString());
setSuccessMessage("The Stored content in PDF is : " + st.trim() + " and stored in the runtime variable: " + testData.getValue());
}
} catch (Exception e) {
logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
setErrorMessage("Cause of Exception: " + ExceptionUtils.getRootCauseMessage(e));
return Result.FAILED;
}
🤖 Prompt for AI Agents
In `@pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadpdfContent.java`
around lines 43 - 55, The PDDocument obtained via PDFUtils.getPDDocument is not
closed and the exception handler calls e.getCause().toString() which can NPE;
change the PDDocument usage in the method (where PDFUtils.getPDDocument,
PDDocument and PDFTextStripper are used) to a try-with-resources block so the
PDDocument is automatically closed, populate runTimeData and call
setSuccessMessage inside that block, and update the catch block (where logger
and setErrorMessage are used) to avoid e.getCause().toString() by checking if
e.getCause() is null and using e.getMessage() or e.toString() (and include
ExceptionUtils.getStackTrace(e) in the log) when building the error message.

Comment on lines +59 to +66
PDDocument doc = PDFUtils.getPDDocument(url);
String st = new PDFTextStripper().getText(doc);
//sb.append(new PDFTextStripper().getText(doc));
runTimeData = new com.testsigma.sdk.RunTimeData();
runTimeData.setValue(st.trim());
runTimeData.setKey(testData.getValue().toString());
setSuccessMessage("The Stored content in PDF is : " + st.trim() + "and stored in the runtime variable :"
+ testData.getValue());
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "ReadPdfContentWithAuth.java" | head -5

Repository: testsigmahq/testsigma-addons

Length of output: 200


🏁 Script executed:

git ls-files | grep -i "ReadPdfContentWithAuth.java"

Repository: testsigmahq/testsigma-addons

Length of output: 200


🌐 Web query:

PDFBox PDDocument AutoCloseable Closeable resource leak

💡 Result:

Short answer: PDDocument implements Closeable/AutoCloseable and must be closed to avoid resource leaks (or you’ll see the “Warning: You did not close a PDF Document” finalizer message). Use try-with-resources or a try/finally that calls close(). [1][2][3]

Minimal examples:

  • try-with-resources (recommended)
    try (PDDocument doc = PDDocument.load(new File("in.pdf"))) {
    // use doc
    }

  • try/finally
    PDDocument doc = PDDocument.load(new File("in.pdf"));
    try {
    // use doc
    } finally {
    doc.close();
    }

Notes:

  • PDDocument.close() releases the underlying COSDocument and temporary files; failing to call it triggers a finalizer warning and may leave temp files open. [1][3]
  • try-with-resources works because PDDocument implements AutoCloseable/Closeable. [1][2]

Sources:
[1] PDDocument Javadoc (PDFBox). (pdfbox.apache.org)
[2] Java try-with-resources documentation. (docs.oracle.com)
[3] StackOverflow / PDFBox warnings and finalize behavior. (stackoverflow.com)

Citations:


🌐 Web query:

Apache PDFBox PDDocument try-with-resources

💡 Result:

Yes — PDDocument implements Closeable/AutoCloseable, so use it with try-with-resources to ensure it is closed even on exceptions.

Example:

try (PDDocument doc = PDDocument.load(new File("in.pdf"))) {
    // modify/read document
    doc.save("out.pdf"); // save while open
} // doc.close() called automatically here

Notes:

  • call save(...) while the document is open; try-with-resources will call close() (which may throw IOException) after the block. [1][2]
  • closing is required to release temporary files and resources; failing to close triggers a warning and finalizer cleanup. [2][3]

Sources:

  • PDDocument Javadoc (close(), AutoCloseable). [1]
  • PDFBox FAQ — close PDDocument in finally / use try-with-resources. [2]
  • StackOverflow discussion confirming save() vs close() behavior and using try-with-resources. [3]

Close PDDocument to prevent resource leaks.

PDDocument implements AutoCloseable and must be closed; otherwise, file handles, temporary files, and memory can leak. Use try-with-resources to ensure proper cleanup even when exceptions occur.

♻️ Suggested fix
-            try {
-                PDDocument doc = PDFUtils.getPDDocument(url);
-                String st = new PDFTextStripper().getText(doc);
+            try (PDDocument doc = PDFUtils.getPDDocument(url)) {
+                String st = new PDFTextStripper().getText(doc);
                 //sb.append(new PDFTextStripper().getText(doc));
                 runTimeData = new com.testsigma.sdk.RunTimeData();
                 runTimeData.setValue(st.trim());
                 runTimeData.setKey(testData.getValue().toString());
                 setSuccessMessage("The Stored content in PDF is : " + st.trim() + "and stored in the runtime variable :"
                         + testData.getValue());
             } catch (Exception e) {
📝 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
PDDocument doc = PDFUtils.getPDDocument(url);
String st = new PDFTextStripper().getText(doc);
//sb.append(new PDFTextStripper().getText(doc));
runTimeData = new com.testsigma.sdk.RunTimeData();
runTimeData.setValue(st.trim());
runTimeData.setKey(testData.getValue().toString());
setSuccessMessage("The Stored content in PDF is : " + st.trim() + "and stored in the runtime variable :"
+ testData.getValue());
try (PDDocument doc = PDFUtils.getPDDocument(url)) {
String st = new PDFTextStripper().getText(doc);
//sb.append(new PDFTextStripper().getText(doc));
runTimeData = new com.testsigma.sdk.RunTimeData();
runTimeData.setValue(st.trim());
runTimeData.setKey(testData.getValue().toString());
setSuccessMessage("The Stored content in PDF is : " + st.trim() + "and stored in the runtime variable :"
testData.getValue());
} catch (Exception e) {
🤖 Prompt for AI Agents
In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/ReadPdfContentWithAuth.java`
around lines 59 - 66, The PDDocument obtained via PDFUtils.getPDDocument is
never closed, risking resource leaks; wrap the PDDocument usage in a
try-with-resources (or explicitly close in finally) where you call
PDFUtils.getPDDocument() and create the PDFTextStripper, then read text and
populate runTimeData (the runTimeData.setValue and setKey calls) and call
setSuccessMessage using the extracted st.trim() and testData.getValue(),
ensuring PDDocument is closed even on exceptions; modify the block around
PDFUtils.getPDDocument, PDFTextStripper, runTimeData, and setSuccessMessage
accordingly.

Comment on lines +40 to +41
PDDocument doc = PDFUtils.getPDDocument(url);
String st=new PDFTextStripper().getText(doc);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Please provide:
# 1. Confirmation that the file exists
# 2. The actual location of the file
# 3. Or the actual code snippet around lines 40-41

Repository: testsigmahq/testsigma-addons

Length of output: 200


🌐 Web query:

PDFBox PDDocument AutoCloseable close resource leak

💡 Result:

Short answer: PDDocument must be closed (it implements Closeable/AutoCloseable); not closing it (or underlying streams/caches) can leak temp files, memory, or soft-referenced resources. Use try-with-resources or always call close() in finally; also keep PDFBox up-to-date because several leaks were fixed (resource cache, input streams, scratch files). [1][2][3][4][5]

Recommended fixes (minimal):

  • Use try-with-resources:
    PDDocument doc = PDDocument.load(path);
    try (PDDocument d = PDDocument.load(path)) { /* use d */ } // auto-closes. [5][1]
  • If you must manage manually, always call doc.close() in finally (or ensure close is called before GC). [2]
  • When processing many pages/docs: clear or replace the PDDocument resource cache (PDDocument#setResourceCache or disable caching) and consider MemoryUsageSetting.setupTempFileOnly() for large files. This avoids SoftReference/cache retention. [3]
  • Ensure any InputStreams you pass to PDFBox are closed (some prior versions left streams open; fixes landed in later versions). Keep PDFBox updated (check release notes / JIRA). [4]

If you want, tell me:

  • which PDFBox version and JDK you use and I’ll point to specific fixes/workarounds.

Close PDDocument to avoid resource leaks.

PDDocument is an AutoCloseable resource that must be closed to prevent leaking file handles, temporary files, and memory. Convert to try-with-resources to ensure proper cleanup.

♻️ Suggested fix
-        try {
-            PDDocument doc = PDFUtils.getPDDocument(url);
-            String st=new PDFTextStripper().getText(doc);
+        try (PDDocument doc = PDFUtils.getPDDocument(url)) {
+            String st = new PDFTextStripper().getText(doc);
             
             if(st.trim().contains(testData.getValue().toString())) {
                 setSuccessMessage("Assertion passed PDF content contains test data" + testData.getValue());
                 logger.info("Assertion passed PDF content contains test data" + testData.getValue());
             }else {
📝 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
PDDocument doc = PDFUtils.getPDDocument(url);
String st=new PDFTextStripper().getText(doc);
try (PDDocument doc = PDFUtils.getPDDocument(url)) {
String st = new PDFTextStripper().getText(doc);
if(st.trim().contains(testData.getValue().toString())) {
setSuccessMessage("Assertion passed PDF content contains test data" + testData.getValue());
logger.info("Assertion passed PDF content contains test data" + testData.getValue());
}else {
🤖 Prompt for AI Agents
In `@pdf_actions_21/src/main/java/com/testsigma/addons/web/VerifypdfContent.java`
around lines 40 - 41, The code in VerifypdfContent calls
PDFUtils.getPDDocument(url) and uses new PDFTextStripper().getText(doc) without
closing the PDDocument; wrap the PDDocument creation in a try-with-resources
(try (PDDocument doc = PDFUtils.getPDDocument(url)) { String st = new
PDFTextStripper().getText(doc); ... }) so the PDDocument is always closed and
resources are not leaked; keep usage of PDFTextStripper inside the try block and
propagate or handle exceptions as needed.

Comment on lines +36 to +58
try {
PDDocument doc = PDFUtils.getPDDocument(driver.getCurrentUrl());

PDFTextStripper reader = new PDFTextStripper();
reader.setStartPage(Integer.parseInt(testData2.getValue().toString()));
reader.setEndPage(Integer.parseInt(testData3.getValue().toString()));
String content = reader.getText(doc);

if(content.contains(testData.getValue().toString())){
setSuccessMessage(SUCCESS_MESSAGE +testData.getValue().toString()+" in given range of pages ");
logger.info(content);
return Result.SUCCESS;

}else {
setErrorMessage(ERROR_MESSAGE +testData.getValue().toString()+" in given range of pages ");
logger.warn(content);
return Result.FAILED;
}
} catch (Exception e) {
logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
setErrorMessage(ERROR_MESSAGE + " " + "Cause of Exception:" + e.getCause().toString());
return Result.FAILED;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Resource leak: PDDocument is never closed.

PDDocument implements Closeable and must be explicitly closed to release file handles and memory. Additionally, e.getCause() can return null, causing an NPE in the catch block.

Proposed fix
         try {
             PDDocument doc = PDFUtils.getPDDocument(driver.getCurrentUrl());
-            
-            PDFTextStripper reader = new PDFTextStripper();
-            reader.setStartPage(Integer.parseInt(testData2.getValue().toString()));
-            reader.setEndPage(Integer.parseInt(testData3.getValue().toString()));
-            String content = reader.getText(doc);
-            
-            if(content.contains(testData.getValue().toString())){
-            	setSuccessMessage(SUCCESS_MESSAGE +testData.getValue().toString()+" in given range of pages ");
-                logger.info(content);
-                return Result.SUCCESS;
-            	
-            }else {
-            	setErrorMessage(ERROR_MESSAGE +testData.getValue().toString()+" in given range of pages ");
-                logger.warn(content);
-                return Result.FAILED;
+            try {
+                PDFTextStripper reader = new PDFTextStripper();
+                reader.setStartPage(Integer.parseInt(testData2.getValue().toString()));
+                reader.setEndPage(Integer.parseInt(testData3.getValue().toString()));
+                String content = reader.getText(doc);
+                
+                if(content.contains(testData.getValue().toString())){
+                    setSuccessMessage(SUCCESS_MESSAGE + testData.getValue().toString() + " in given range of pages ");
+                    logger.info("Text found in PDF page range");
+                    return Result.SUCCESS;
+                } else {
+                    setErrorMessage(ERROR_MESSAGE + testData.getValue().toString() + " in given range of pages ");
+                    logger.warn("Text not found in PDF page range");
+                    return Result.FAILED;
+                }
+            } finally {
+                doc.close();
             }
         } catch (Exception e) {
             logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
-            setErrorMessage(ERROR_MESSAGE + " " + "Cause of Exception:" + e.getCause().toString());
+            setErrorMessage(ERROR_MESSAGE + " Cause of Exception:" + ExceptionUtils.getRootCauseMessage(e));
             return Result.FAILED;
         }
📝 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
try {
PDDocument doc = PDFUtils.getPDDocument(driver.getCurrentUrl());
PDFTextStripper reader = new PDFTextStripper();
reader.setStartPage(Integer.parseInt(testData2.getValue().toString()));
reader.setEndPage(Integer.parseInt(testData3.getValue().toString()));
String content = reader.getText(doc);
if(content.contains(testData.getValue().toString())){
setSuccessMessage(SUCCESS_MESSAGE +testData.getValue().toString()+" in given range of pages ");
logger.info(content);
return Result.SUCCESS;
}else {
setErrorMessage(ERROR_MESSAGE +testData.getValue().toString()+" in given range of pages ");
logger.warn(content);
return Result.FAILED;
}
} catch (Exception e) {
logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
setErrorMessage(ERROR_MESSAGE + " " + "Cause of Exception:" + e.getCause().toString());
return Result.FAILED;
}
try {
PDDocument doc = PDFUtils.getPDDocument(driver.getCurrentUrl());
try {
PDFTextStripper reader = new PDFTextStripper();
reader.setStartPage(Integer.parseInt(testData2.getValue().toString()));
reader.setEndPage(Integer.parseInt(testData3.getValue().toString()));
String content = reader.getText(doc);
if(content.contains(testData.getValue().toString())){
setSuccessMessage(SUCCESS_MESSAGE + testData.getValue().toString() + " in given range of pages ");
logger.info("Text found in PDF page range");
return Result.SUCCESS;
} else {
setErrorMessage(ERROR_MESSAGE + testData.getValue().toString() + " in given range of pages ");
logger.warn("Text not found in PDF page range");
return Result.FAILED;
}
} finally {
doc.close();
}
} catch (Exception e) {
logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
setErrorMessage(ERROR_MESSAGE + " Cause of Exception:" + ExceptionUtils.getRootCauseMessage(e));
return Result.FAILED;
}
🤖 Prompt for AI Agents
In
`@pdf_actions_21/src/main/java/com/testsigma/addons/web/VerifyTextinparticularpage.java`
around lines 36 - 58, PDDocument returned by PDFUtils.getPDDocument(...) is
never closed and the catch block calls e.getCause().toString() which may NPE;
update VerifyTextinparticularpage to use a try-with-resources (or ensure a
finally block) to close the PDDocument (the local variable doc) after using
PDFTextStripper, and replace e.getCause().toString() with a null-safe expression
(e.g., check e.getCause() != null ? e.getCause().toString() : e.toString()) when
building the error message so no NPE occurs in the catch.

@@ -0,0 +1 @@
testsigma-sdk.api.key=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIyNTgxZDNlYy02Zjk2LTg3NDktZThmNS1hYjEwMWIwZDA1NTQiLCJ1bmlxdWVJZCI6IjM0NzEiLCJpZGVudGl0eUFjY291bnRVVUlkIjoiODZlMGQ1ODUtZTVlYi05NmIxLTAyZDktOTRkODM3N2RiMzlmIn0.zAe-Ni4WTqKche3ccgXoMY7tivt6fymFJrYNfs-AXJu7pbpSpn0N0xFmv6oWSvDzGq5tevdgKrG719SBZKulGg No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Remove hardcoded API key from source control.

Committing API keys/secrets to a repository exposes them publicly and poses a significant security risk. This JWT contains identifiable information (uniqueId, identityAccountUUId) that could be exploited.

Recommended approaches:

  1. Use environment variables: testsigma-sdk.api.key=${TESTSIGMA_API_KEY}
  2. Use a .properties.template file with placeholder values and add the actual .properties file to .gitignore
  3. Use a secrets management solution

If this key has already been committed, rotate it immediately after removal.

🤖 Prompt for AI Agents
In `@pdf_actions_21/src/main/resources/testsigma-sdk.properties` at line 1, Remove
the hardcoded JWT value assigned to testsigma-sdk.api.key in
testsigma-sdk.properties and replace it with a reference to an environment
variable (e.g., use the placeholder form for TESTSIGMA_API_KEY) or move the
entry into a template file; create testsigma-sdk.properties.template containing
testsigma-sdk.api.key placeholder and add the real testsigma-sdk.properties to
.gitignore so secrets are not committed, then rotate the exposed API key
immediately. Ensure you update any code that reads testsigma-sdk.api.key to fall
back to the TESTSIGMA_API_KEY env var if present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants