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