diff --git a/xml_verification_/pom.xml b/xml_verification_/pom.xml
new file mode 100644
index 0000000..02f2155
--- /dev/null
+++ b/xml_verification_/pom.xml
@@ -0,0 +1,106 @@
+
+
+ 4.0.0
+ com.testsigma.addons
+ xml_verification_
+ 1.0.3
+ jar
+
+
+ UTF-8
+ 11
+ 11
+ 1.2.13_cloud
+ 5.8.0-M1
+ 1.0.0
+ 3.2.1
+ 1.18.20
+
+
+
+
+
+ com.testsigma
+ testsigma-java-sdk
+ ${testsigma.sdk.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ true
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.jupiter.version}
+ test
+
+
+ org.testng
+ testng
+ 6.14.3
+
+
+
+ org.seleniumhq.selenium
+ selenium-java
+ 4.14.1
+
+
+
+ io.appium
+ java-client
+ 9.0.0
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.13.0
+
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
+ org.apache.commons
+ commons-lang3
+ 3.14.0
+
+
+
+ xml_verification_
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ ${maven.source.plugin.version}
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+
+
diff --git a/xml_verification_/src/main/java/com/testsigma/addons/utilities/XMLUtility.java b/xml_verification_/src/main/java/com/testsigma/addons/utilities/XMLUtility.java
new file mode 100644
index 0000000..59f2d6e
--- /dev/null
+++ b/xml_verification_/src/main/java/com/testsigma/addons/utilities/XMLUtility.java
@@ -0,0 +1,83 @@
+package com.testsigma.addons.utilities;
+
+import com.testsigma.sdk.Logger;
+import org.apache.commons.io.FileUtils;
+import org.openqa.selenium.WebDriver;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathFactory;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+public class XMLUtility {
+
+ WebDriver driver;
+ Logger logger;
+
+ public XMLUtility(WebDriver driver, Logger logger) {
+ this.driver = driver;
+ this.logger = logger;
+ }
+ public Document parseXML(String xmlContent) throws Exception {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ return builder.parse(new ByteArrayInputStream(xmlContent.getBytes()));
+ }
+
+ public Document parseXML(File file) throws Exception {
+ if (file == null || !file.exists() || file.length() == 0) {
+ logger.warn("Invalid file: " + (file == null ? "null" : file.getAbsolutePath()));
+ throw new Exception("Invalid file: " + (file == null ? "null" : file.getAbsolutePath()));
+ }
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true); // Enable namespace awareness
+ DocumentBuilder builder = factory.newDocumentBuilder();
+
+ logger.info("Parsing XML file: " + file.getAbsolutePath());
+ Document document = builder.parse(file);
+
+ document.getDocumentElement().normalize(); // Normalize the document
+ logger.info("Root element: " + document.getDocumentElement().getNodeName());
+ return document;
+ }
+
+
+ public void removeNodesByXPath(Document doc, String xpathExpression) throws Exception {
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ XPathExpression xPathExpr = xpath.compile(xpathExpression);
+ NodeList nodes = (NodeList) xPathExpr.evaluate(doc, XPathConstants.NODESET);
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node node = nodes.item(i);
+ if (node != null && node.getParentNode() != null) {
+ node.getParentNode().removeChild(node);
+ }
+ }
+ }
+
+
+ public File urlToFileConverter(String fileName, String url) throws IOException {
+ if (url.startsWith("https://")) {
+ logger.info("Given is s3 url ...File name:" + fileName);
+ URL urlObject = new URL(url);
+ File tempFile = File.createTempFile(fileName.split("\\.")[0], "." + fileName.split("\\.")[1]);
+ FileUtils.copyURLToFile(urlObject,tempFile);
+ logger.info("Temp file created with name for s3 file" + tempFile.getName() + " at path " + tempFile.getAbsolutePath());
+ return tempFile;
+ } else {
+ logger.info("Given is local file path..");
+ return new File(url);
+ }
+ }
+
+
+}
diff --git a/xml_verification_/src/main/java/com/testsigma/addons/web/CompareLocalXMLFiles.java b/xml_verification_/src/main/java/com/testsigma/addons/web/CompareLocalXMLFiles.java
new file mode 100644
index 0000000..a16a7a3
--- /dev/null
+++ b/xml_verification_/src/main/java/com/testsigma/addons/web/CompareLocalXMLFiles.java
@@ -0,0 +1,87 @@
+package com.testsigma.addons.web;
+
+import com.testsigma.addons.utilities.XMLUtility;
+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.TestData;
+import lombok.Data;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.openqa.selenium.NoSuchElementException;
+import org.w3c.dom.Document;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+
+@Data
+@Action(actionText = "Xml: Verify if local files with filepath filepath1 and filepath filepath2 are equal while ignoring specific XPaths X-Paths",
+ description = "Verifies if files with given filepath are equal while ignoring given xPaths " +
+ "(separate xPaths by comma) e.g: xpath1, xpath2",
+ applicationType = ApplicationType.WEB)
+public class CompareLocalXMLFiles extends WebAction {
+
+ @TestData(reference = "filepath1")
+ private com.testsigma.sdk.TestData testData1;
+
+ @TestData(reference = "filepath2")
+ private com.testsigma.sdk.TestData testData2;
+
+ @TestData(reference = "X-Paths")
+ private com.testsigma.sdk.TestData testData3;
+
+ @Override
+ protected Result execute() throws NoSuchElementException {
+ Result result ;
+ try {
+ XMLUtility xmlUtility = new XMLUtility(driver, logger);
+
+ // Get the file paths
+ String xPathsToIgnore = testData3.getValue().toString();
+ logger.info("xPaths to be ignored: " + xPathsToIgnore);
+
+ File baseFile = File.createTempFile("tempFile1_", ".xml");
+ File actualFile = File.createTempFile("tempFile2_", ".xml");
+
+ logger.info("created temp files");
+ baseFile = xmlUtility.urlToFileConverter(baseFile.getName(), testData1.getValue().toString());
+ actualFile = xmlUtility.urlToFileConverter(actualFile.getName(), testData2.getValue().toString());
+
+ logger.info("converted temp files");
+ // deleting files on completion of execution
+ baseFile.deleteOnExit();
+ actualFile.deleteOnExit();
+
+ // Parsing XML files
+ Document doc1 = xmlUtility.parseXML(baseFile);
+ Document doc2 = xmlUtility.parseXML(actualFile);
+ logger.info("Parsed the xml files");
+ // Removing nodes based on XPath expressions
+ String[] xpathArray = xPathsToIgnore.split(",");
+ for (String xpathExpression : xpathArray) {
+ xmlUtility.removeNodesByXPath(doc1, xpathExpression.trim());
+ xmlUtility.removeNodesByXPath(doc2, xpathExpression.trim());
+ }
+
+ logger.info("successfully Ignored xPaths of the given xml files");
+
+ // Compare the modified documents
+ boolean isEqual = doc1.isEqualNode(doc2);
+ if (isEqual) {
+ setSuccessMessage("The XML files are equal.");
+ result = Result.SUCCESS;
+ } else {
+ setErrorMessage("The base XML file is not same as the actual XML file.");
+ result = Result.FAILED;
+ }
+ return result;
+
+ } catch (Exception e) {
+ setErrorMessage("An error occurred, please check if the Xml file is not damaged " + ExceptionUtils.getMessage(e));
+ logger.info(ExceptionUtils.getStackTrace(e));
+ return Result.FAILED;
+ }
+ }
+}
diff --git a/xml_verification_/src/main/java/com/testsigma/addons/web/CompareXMLTextsIgnoringXPaths.java b/xml_verification_/src/main/java/com/testsigma/addons/web/CompareXMLTextsIgnoringXPaths.java
new file mode 100644
index 0000000..f0759fd
--- /dev/null
+++ b/xml_verification_/src/main/java/com/testsigma/addons/web/CompareXMLTextsIgnoringXPaths.java
@@ -0,0 +1,71 @@
+package com.testsigma.addons.web;
+
+import com.testsigma.addons.utilities.XMLUtility;
+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.TestData;
+import lombok.Data;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.w3c.dom.Document;
+
+import java.util.NoSuchElementException;
+
+@Data
+@Action(actionText = "Xml: Verify if xmlText text1 is equal to xmlText text2 while ignoring specific XPaths X-paths",
+ description = "Verifies if texts with given xml content are equal while ignoring given xPaths" +
+ " (separate xPaths by comma) e.g: xpath1, xpath2",
+ applicationType = ApplicationType.WEB)
+public class CompareXMLTextsIgnoringXPaths extends WebAction {
+
+ @TestData(reference = "text1")
+ private com.testsigma.sdk.TestData testData1;
+
+ @TestData(reference = "text2")
+ private com.testsigma.sdk.TestData testData2;
+
+ @TestData(reference = "X-paths")
+ private com.testsigma.sdk.TestData testData3;
+
+ @Override
+ protected Result execute() throws NoSuchElementException {
+ Result result = Result.SUCCESS;
+ try {
+ String filePath1 = testData1.getValue().toString();
+ String filePath2 = testData2.getValue().toString();
+ String xPathsToIgnore = testData3.getValue().toString();
+ logger.info("xPathsToIgnore: " + xPathsToIgnore);
+ XMLUtility xmlUtility = new XMLUtility(driver, logger);
+ Document doc1 = xmlUtility.parseXML(filePath1);
+ Document doc2 = xmlUtility.parseXML(filePath2);
+ logger.info("Text1 after parsing into xml " + doc1);
+
+ // Remove nodes based on XPath expressions
+ String[] xpathArray = xPathsToIgnore.split(",");
+ for (String xpathExpression : xpathArray) {
+ xmlUtility.removeNodesByXPath(doc1, xpathExpression.trim());
+ xmlUtility.removeNodesByXPath(doc2, xpathExpression.trim());
+ }
+
+ logger.info("Text1 after ignoring xPaths " + doc1);
+ logger.info("Text2 after parsing xPaths " + doc2);
+ // Compare the modified documents
+ boolean isEqual = doc1.isEqualNode(doc2);
+ if (isEqual) {
+ setSuccessMessage("the given texts are equal");
+ result = Result.SUCCESS;
+ } else {
+ setErrorMessage("the given texts are not equal");
+ result = Result.FAILED;
+ }
+ return result;
+
+ } catch (Exception e) {
+ setErrorMessage("Error occurred while comparing: " + ExceptionUtils.getStackTrace(e));
+ logger.info(ExceptionUtils.getStackTrace(e));
+ return Result.FAILED;
+ }
+ }
+
+}
diff --git a/xml_verification_/src/main/java/com/testsigma/addons/web/ExtractTheContentOfXML.java b/xml_verification_/src/main/java/com/testsigma/addons/web/ExtractTheContentOfXML.java
new file mode 100644
index 0000000..4be635e
--- /dev/null
+++ b/xml_verification_/src/main/java/com/testsigma/addons/web/ExtractTheContentOfXML.java
@@ -0,0 +1,66 @@
+package com.testsigma.addons.web;
+
+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 org.apache.commons.lang3.exception.ExceptionUtils;
+import org.openqa.selenium.NoSuchElementException;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
+
+@Data
+@Action(actionText = "Xml: Extract and store the content in the runtime-variable for XML filepath",
+ description = "Extracts the content of xml and stores it in the runtime variable",
+ applicationType = ApplicationType.WEB)
+public class ExtractTheContentOfXML extends WebAction {
+
+ @TestData(reference = "filepath")
+ private com.testsigma.sdk.TestData filepath;
+ @TestData(reference = "runtime-variable", isRuntimeVariable = true)
+ private com.testsigma.sdk.TestData targetVariable;
+ @RunTimeData
+ private com.testsigma.sdk.RunTimeData runTimeData;
+
+ @Override
+ protected Result execute() throws NoSuchElementException {
+ final String SUCCESS_MESSAGE = "Successfully extracted content and stored it in runtime variable";
+ final String FAILURE_MESSAGE = "Failed to extract content";
+ logger.info("Extracting the content of XML filepath and storing it in the runtime-variable");
+ logger.info("Test Data (Filepath): " + filepath.getValue().toString());
+ Result result = Result.SUCCESS;
+
+ try {
+ HttpClient client = HttpClient.newHttpClient();
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(new URI(filepath.getValue().toString()))
+ .build();
+
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
+
+ String xmlContent = new String(response.body().readAllBytes(), StandardCharsets.UTF_8);
+
+
+ logger.info("Extracted XML Content: " + xmlContent);
+ runTimeData.setValue(xmlContent);
+ runTimeData.setKey(targetVariable.getValue().toString());
+ setSuccessMessage(SUCCESS_MESSAGE);
+
+ } catch (Exception e) {
+ logger.info("Error occurred while extracting XML content: " + ExceptionUtils.getMessage(e));
+ setErrorMessage(FAILURE_MESSAGE);
+ result = Result.FAILED;
+ }
+
+ return result;
+ }
+
+}
diff --git a/xml_verification_/src/main/resources/testsigma-sdk.properties b/xml_verification_/src/main/resources/testsigma-sdk.properties
new file mode 100644
index 0000000..649062a
--- /dev/null
+++ b/xml_verification_/src/main/resources/testsigma-sdk.properties
@@ -0,0 +1 @@
+testsigma-sdk.api.key=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIyMjMyMmM2Ni04NWYzLWIyN2UtN2FiOS0zM2U2M2Q4OWM1MGIiLCJ1bmlxdWVJZCI6IjM4NzkiLCJpZGVudGl0eUFjY291bnRVVUlkIjoiMzUifQ._GnbUr3qKsF8IpySoxg0jrBlT8FqV7IF26lLesm1JzMmMl1CazFNeKkso_FKMu8DwmCwPqI8SaTb6qpGgmlABw
\ No newline at end of file