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
121 changes: 121 additions & 0 deletions pdf_actions_21/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.testsigma.addons</groupId>
<artifactId>pdf_actions_21</artifactId>
<version>1.0.2</version>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<testsigma.sdk.version>1.2.13_cloud</testsigma.sdk.version>
<junit.jupiter.version>5.8.0-M1</junit.jupiter.version>
<testsigma.addon.maven.plugin>1.0.0</testsigma.addon.maven.plugin>
<maven.source.plugin.version>3.2.1</maven.source.plugin.version>
<lombok.version>1.18.30</lombok.version>

</properties>

<dependencies>
<dependency>
<groupId>com.testsigma</groupId>
<artifactId>testsigma-java-sdk</artifactId>
<version>${testsigma.sdk.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<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>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.14.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>9.0.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.0</version>
</dependency>

</dependencies>
<build>
<finalName>pdf_actions_21</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven.source.plugin.version}</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.testsigma.addons.pdf_action_with_file_input;

import com.testsigma.sdk.ApplicationType;
import com.testsigma.sdk.Result;
import com.testsigma.sdk.annotation.Action;
import com.testsigma.sdk.annotation.TestData;
import lombok.Data;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;
import java.net.Authenticator;
import java.net.PasswordAuthentication;

@Data
@Action(actionText = "Verify if the pdf at file path pdf_file_path contains text test-data using username Username_Value and password Password_Value",
description = "Validates whether the given test-data is present in the PDF (file path or URL, with optional auth for URLs)",
applicationType = ApplicationType.WEB)
public class ContainsTextPDFWithAuth extends PdfFileInputBase {

private static final String SUCCESS_MESSAGE = "Assertion passed PDF content contains test data";
private static final String ERROR_MESSAGE = "Assertion failed PDF content does not contain test data";

@TestData(reference = "pdf_file_path")
private com.testsigma.sdk.TestData pdfFilePath;
@TestData(reference = "test-data")
private com.testsigma.sdk.TestData testData;
@TestData(reference = "Username_Value")
private com.testsigma.sdk.TestData username;
@TestData(reference = "Password_Value")
private com.testsigma.sdk.TestData password;

@Override
public Result execute() {
try {
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username.getValue().toString(),
password.getValue().toString().toCharArray());
}
});

logger.info("Initiating execution");
logger.debug("pdf_file_path: " + pdfFilePath.getValue() + ", test-data: " + testData.getValue());
String pathOrUrl = pdfFilePath.getValue().toString().trim();
File basePDF = urlToFileConverter("base.pdf", pathOrUrl);
if (!verifyPdfFile(basePDF)) {
return Result.FAILED;
}
try (PDDocument doc = loadPdfDocument(basePDF)) {
String text = new PDFTextStripper().getText(doc);
if (text.contains((CharSequence) testData.getValue())) {
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 | 🔴 Critical

Unsafe cast (CharSequence) testData.getValue() — will throw ClassCastException if value is not a CharSequence.

All other actions in this PR consistently use .getValue().toString(). This cast will fail at runtime if the SDK returns a non-String type.

Proposed fix
-                if (text.contains((CharSequence) testData.getValue())) {
+                if (text.contains(testData.getValue().toString())) {
📝 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
if (text.contains((CharSequence) testData.getValue())) {
if (text.contains(testData.getValue().toString())) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pdf_actions_21/src/main/java/com/testsigma/addons/pdf_action_with_file_input/ContainsTextPDFWithAuth.java`
at line 54, Replace the unsafe cast in ContainsTextPDFWithAuth where
text.contains((CharSequence) testData.getValue()) is used: instead call
text.contains(testData.getValue().toString()) (or use
String.valueOf(testData.getValue()) for null-safety) so the code always compares
a String and avoids a ClassCastException when testData.getValue() is not a
CharSequence.

setSuccessMessage(SUCCESS_MESSAGE + " " + testData.getValue());
return Result.SUCCESS;
} else {
setErrorMessage(ERROR_MESSAGE + " " + testData.getValue());
logger.warn("Error message: " + text);
return Result.FAILED;
}
}
} catch (Exception e) {
String errorMessage = ExceptionUtils.getStackTrace(e);
logger.info(errorMessage);
setErrorMessage(ERROR_MESSAGE + ": " + errorMessage);
return Result.FAILED;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.testsigma.addons.pdf_action_with_file_input;

import com.testsigma.sdk.ApplicationType;
import com.testsigma.sdk.Result;
import com.testsigma.sdk.annotation.Action;
import com.testsigma.sdk.annotation.TestData;
import lombok.Data;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;

@Data
@Action(actionText = "Verify if the pdf at file path pdf_file_path contains text test_data",
description = "Extracts the text from the PDF (file path or URL as testdata) and verifies it contains the given text",
applicationType = ApplicationType.WEB)
public class ContainsTextpdf extends PdfFileInputBase {

private static final String SUCCESS_MESSAGE = "Assertion passed PDF content contains test data";
private static final String ERROR_MESSAGE = "Assertion failed PDF content does not contain test data";

@TestData(reference = "pdf_file_path")
private com.testsigma.sdk.TestData pdfFilePath;
@TestData(reference = "test_data")
private com.testsigma.sdk.TestData testData;

@Override
public Result execute() {
logger.info("Initiating execution");
logger.debug("pdf_file_path: " + pdfFilePath.getValue() + ", test_data: " + testData.getValue());
String pathOrUrl = pdfFilePath.getValue().toString().trim();
File basePDF = urlToFileConverter("base.pdf", pathOrUrl);
if (!verifyPdfFile(basePDF)) {
return Result.FAILED;
}
try (PDDocument doc = loadPdfDocument(basePDF)) {
String text = new PDFTextStripper().getText(doc);
if (text.contains((CharSequence) testData.getValue())) {
setSuccessMessage(SUCCESS_MESSAGE + " " + testData.getValue());
logger.info(SUCCESS_MESSAGE + " " + testData.getValue());
return Result.SUCCESS;
} else {
setErrorMessage(ERROR_MESSAGE + " " + testData.getValue());
logger.warn(ERROR_MESSAGE + " " + testData.getValue() + ":" + text);
return Result.FAILED;
}
} catch (Exception e) {
String errorMessage = ExceptionUtils.getStackTrace(e);
setErrorMessage(ERROR_MESSAGE + " " + testData.getValue() + " Cause of Exception:" + errorMessage);
logger.warn(ERROR_MESSAGE + " " + testData.getValue() + " Cause of Exception:" + errorMessage);
return Result.FAILED;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.testsigma.addons.pdf_action_with_file_input;

import com.testsigma.sdk.ApplicationType;
import com.testsigma.sdk.Result;
import com.testsigma.sdk.annotation.Action;
import com.testsigma.sdk.annotation.RunTimeData;
import com.testsigma.sdk.annotation.TestData;
import com.testsigma.addons.util.PdfExtractionUtil;
import com.testsigma.addons.util.PdfExtractionUtil.MatchResult;
import lombok.Data;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;

@Data
@Action(actionText = "Extract No_Of_Character characters after occurrence Occurrence of search_pattern from PDF at file path pdf_file_path using match type Match_Type and store in a runtime variable Variable_Name",
description = "Extracts N characters after the specified occurrence of search_pattern. Match_Type: choose 'Text' for literal text match or 'Regex' for regex pattern. Occurrence: 1=first, 2=second, etc.",
applicationType = ApplicationType.WEB)
public class ExtractCharsAfterByOccurrence extends PdfFileInputBase {

private static final String ERROR_MESSAGE = "Issue in the Operation";
private static final String OCCURRENCE_NOT_FOUND = "Occurrence %d of '%s' not found in PDF. Found only %d occurrence(s).";

@TestData(reference = "pdf_file_path")
private com.testsigma.sdk.TestData pdfFilePath;
@TestData(reference = "No_Of_Character")
private com.testsigma.sdk.TestData noOfCharacters;
@TestData(reference = "search_pattern")
private com.testsigma.sdk.TestData searchPattern;
@TestData(reference = "Occurrence")
private com.testsigma.sdk.TestData occurrence;
@TestData(reference = "Match_Type")
private com.testsigma.sdk.TestData matchType;
@TestData(reference = "Variable_Name", isRuntimeVariable = true)
private com.testsigma.sdk.TestData variableName;

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

@Override
public Result execute() {
logger.info("Initiating execution");
String pathOrUrl = pdfFilePath.getValue().toString().trim();
File basePDF = urlToFileConverter("base.pdf", pathOrUrl);
if (!verifyPdfFile(basePDF)) {
return Result.FAILED;
}
try (PDDocument doc = loadPdfDocument(basePDF)) {
String content = new PDFTextStripper().getText(doc);
String pattern = searchPattern.getValue().toString();
int occurrenceNum = parseOccurrence(occurrence);
boolean useRegex = parseMatchType(matchType);

MatchResult match = PdfExtractionUtil.findOccurrence(content, pattern, occurrenceNum, useRegex);
if (match == null) {
int count = PdfExtractionUtil.countOccurrences(content, pattern, useRegex);
setErrorMessage(String.format(OCCURRENCE_NOT_FOUND, occurrenceNum, pattern, count));
return Result.FAILED;
}

int numChars = Integer.parseInt(noOfCharacters.getValue().toString());
String extracted = PdfExtractionUtil.extractCharsAfter(content, match, numChars);

runTimeData = new com.testsigma.sdk.RunTimeData();
runTimeData.setValue(extracted);
runTimeData.setKey(variableName.getValue().toString());
setSuccessMessage("Extracted " + numChars + " characters after occurrence " + occurrenceNum + " i.e " + extracted + " and stored in runtime variable " + variableName.getValue());
return Result.SUCCESS;
} catch (Exception e) {
logger.debug("Exception: " + ExceptionUtils.getStackTrace(e));
setErrorMessage(ERROR_MESSAGE + " Cause: " + (e.getCause() != null ? e.getCause().toString() : e.getMessage()));
return Result.FAILED;
}
}

private static int parseOccurrence(com.testsigma.sdk.TestData occurrence) {
if (occurrence == null || occurrence.getValue() == null || occurrence.getValue().toString().trim().isEmpty()) {
return 1;
}
try {
return Math.max(1, Integer.parseInt(occurrence.getValue().toString().trim()));
} catch (NumberFormatException e) {
return 1;
}
}

/** Match_Type allowed values: "Text" (or "text input") = literal match, "Regex" (or "regex input") = regex match. */
private static boolean parseMatchType(com.testsigma.sdk.TestData matchType) {
if (matchType == null || matchType.getValue() == null) return false;
String v = matchType.getValue().toString().trim().toLowerCase();
return "regex".equals(v) || "regex input".equals(v);
}
}
Loading