All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ats.tools.report.XmlReport Maven / Gradle / Ivy

The newest version!
package com.ats.tools.report;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import com.ats.executor.ActionTestScript;
import com.ats.recorder.ShadowScript;
import com.ats.recorder.TestError;
import com.ats.recorder.TestSummary;
import com.ats.recorder.VisualAction;
import com.ats.recorder.VisualReport;
import com.ats.script.Script;
import com.ats.script.ScriptHeader;
import com.ats.script.actions.Action;
import com.ats.tools.Utils;
import com.ats.tools.logger.ExecutionLogger;
import com.ats.tools.logger.levels.AtsLogger;
import com.ats.tools.report.analytics.ActionsDuration;
import com.ats.tools.report.analytics.ActionsType;
import com.ctc.wstx.api.WstxInputProperties;
import com.ctc.wstx.stax.WstxInputFactory;
import com.ctc.wstx.sw.SimpleNsStreamWriter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class XmlReport {

	public static String REPORT_DATA_FILE = "actions.xml";

	private static ExecutionLogger insideLogger = new ExecutionLogger();

	private static long dataFileGenerationStartTime;

	public static void main(String[] args) {

		String output = null;
		String testName = null;
		List listArgs = Arrays.asList(args);

		if (listArgs.contains("--help") || listArgs.contains("-h") || listArgs.contains("--h") || listArgs.contains("/?") || listArgs.contains("\\?")) {
			usage();
			return;
		}

		for (int i = 0; i < args.length; i++) {
			String string = args[i];
			if (string.startsWith("--") && i + 1 < args.length) {
				switch (string.substring(2)) {
				case "outputFolder":
				case "output":
				case "reportFolder":
					output = args[i + 1].replaceAll("\"", "");
					break;
				case "testName":
					testName = args[i + 1].replaceAll("\"", "");
					break;
				}
			}
		}

		if (output == null) {
			System.out.println("Error, output folder not defined !");
			return;
		}

		if (testName == null) {
			System.out.println("Error, testName not defined !");
			return;
		}

		final Path outputFolderPath = Paths.get(output).toAbsolutePath();
		if (!outputFolderPath.toFile().exists()) {
			System.out.println("Error, output folder path not found : " + output);
			return;
		}
	}

	public static class InputFactory extends WstxInputFactory {
		public InputFactory() {
			super();
			setProperty(WstxInputProperties.P_MAX_ATTRIBUTE_SIZE, Integer.MAX_VALUE);
		}
	}

	private static void usage() {
		System.out.print("Usage : Experiment dev" + "\n" +
				"This class is use to extract data action from ATSV, convert and generate to actions.xml" + "\n\n" +
				"Parameters usage :" + "\n" +
				"\t--output" + "\t\t\t" + "(mandatory)(absolute or relative path) : parameter used to" + "\n" +
				"\t  outputFolder" + "\t\t" + "specify the input and output folder of generated folder" + "\n" +
				"\t  reportFolder" + "\t\t" + "" + "\n" +
				"\t--testName" + "\t\t\t" + "(mandatory) :" + "\n" +
				"\n\n\n\n");
	}

	public static void createReport(ActionTestScript topScript, Path output, ScriptHeader header, ExecutionLogger execLogger, boolean savePic, boolean cleanAtsv) throws RuntimeException {

		final ShadowScript shadowScript = topScript.getShadowScript();
		final String summaryText = topScript.getSummaryText();
		final String qualifiedName = header.getQualifiedName();
		final File atsvFile = output.resolve(qualifiedName + Script.ATS_VISUAL_FILE_EXTENSION).toFile();
		List actionsSortingOrder = new ArrayList<>();

		boolean addCharts = true;

		if (execLogger == null) {
			execLogger = insideLogger;
		}

		final ExecutionLogger logger = execLogger;

		if (atsvFile.exists()) {
			dataFileGenerationStartTime = System.nanoTime();
			final File xmlFolder = output.resolve(qualifiedName + "_xml").toFile();
			logger.sendInfo("create XML report", xmlFolder.getAbsolutePath());

			final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

			try {
				Utils.deleteRecursive(xmlFolder);
			} catch (FileNotFoundException e) {
			}
			xmlFolder.mkdirs();
			final Path xmlFolderPath = xmlFolder.toPath();
			XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();

			final TestSummary[] testSummary = {null};

			ActionsDuration durationChart = new ActionsDuration();
			ActionsType actionsTypeChart = new ActionsType();
			try (FileInputStream fis = new FileInputStream(atsvFile);

				final AMF3StreamWriter amf3StreamWriter = new AMF3StreamWriter(fis)) {
					amf3StreamWriter.readAndProcessStream(obj -> {
						if (obj instanceof VisualAction data) {
							durationChart.addDuration(data.getDuration());
							actionsTypeChart.addActionType(data.getType());
							actionsSortingOrder.add(data.getTimeLine());
	
						} else if (obj instanceof TestSummary) {
							testSummary[0] = (TestSummary) obj;
							if (testSummary[0].getError() != null && Utils.isNotEmpty(testSummary[0].getError().getScript()) && Utils.isNotEmpty(testSummary[0].getError().getMessage())) {
								if (testSummary[0].getErrors() == null) {
									testSummary[0].setErrors(new ArrayList<>());
								}
								final ObjectMapper objectMapper = new ObjectMapper();
								try {
									List testErrors = objectMapper.readValue(testSummary[0].getError().getMessage(), new TypeReference>() {});
									testSummary[0].setErrors(testErrors);
								} catch (JsonProcessingException e) {
									e.printStackTrace();
								}
							}
						}
					});
				
				amf3StreamWriter.close();
				fis.close();
				
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Throwable e) {
				e.printStackTrace();
			}

			ArrayList visualActions = new ArrayList<>();

			if (shadowScript != null) {
				for (Action action : shadowScript.getActions()) {
					visualActions.add(action.getVisualAction());
					actionsTypeChart.addActionType(action.getVisualAction().getType());
					actionsSortingOrder.add(action.getVisualAction().getTimeLine());
				}
			}

			actionsSortingOrder.sort(Comparator.comparing(aLong -> aLong, Comparator.nullsLast(Comparator.naturalOrder())));
			try (FileWriter fileWriter = new FileWriter(xmlFolder.toPath().resolve("actions.xml").toFile());
					FileInputStream fis = new FileInputStream(atsvFile)) {

				XMLStreamWriter xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(fileWriter);
				xmlStreamWriter.writeStartDocument();

				xmlStreamWriter.writeStartElement("ats"); //Write ats node open element
				xmlStreamWriter.writeAttribute("devReportLVL", "0");
				xmlStreamWriter.writeAttribute("duration", String.valueOf(durationChart.getTotal()));

				AMF3StreamWriter amf3StreamWriter = new AMF3StreamWriter(fis);

				VisualReport report = null;
				try {
					report = (VisualReport) amf3StreamWriter.readObject();
				} catch (Exception e) {
					logger.sendError("Unable to read the report header ->", e.getMessage());
				}

				if (report != null) {
					xmlStreamWriter.writeStartElement("script");//Write script node open element
					if (report.getCpuCount() > 0) {
						xmlStreamWriter.writeAttribute("cpuCount", String.valueOf(report.getCpuCount()));
					}
					if (report.getCpuSpeed() > 0) {
						xmlStreamWriter.writeAttribute("cpuSpeed", String.valueOf(report.getCpuSpeed()));
					}
					if (report.getExternalId() != null) {
						xmlStreamWriter.writeAttribute("externalId", report.getExternalId());
					}
					if (report.getOsInfo() != null) {
						xmlStreamWriter.writeAttribute("osInfo", report.getOsInfo());
					}
					if (report.getId() != null) {
						xmlStreamWriter.writeAttribute("testId", report.getId());
					}
					if (report.getScript() != null) {
						xmlStreamWriter.writeAttribute("testName", report.getScript());
					}
					if (report.getDescription() != null) {
						xmlStreamWriter.writeStartElement("description");
						xmlStreamWriter.writeCharacters(report.getDescription());
						xmlStreamWriter.writeEndElement();
					}

					if (report.getAuthor() != null) {
						xmlStreamWriter.writeStartElement("author");
						xmlStreamWriter.writeCharacters(report.getAuthor());
						xmlStreamWriter.writeEndElement();
					}

					if (report.getPrerequisite() != null) {
						xmlStreamWriter.writeStartElement("prerequisite");
						xmlStreamWriter.writeCharacters(report.getPrerequisite());
						xmlStreamWriter.writeEndElement();
					}

					xmlStreamWriter.writeStartElement("started");
					xmlStreamWriter.writeCharacters(report.getStarted());
					xmlStreamWriter.writeEndElement();

					xmlStreamWriter.writeStartElement("startedFormated");
					xmlStreamWriter.writeCharacters(OffsetDateTime.ofInstant(Instant.ofEpochMilli(Utils.string2Long(report.getStarted())),
							ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd 'at' HH:mm:ss")));
					xmlStreamWriter.writeEndElement();

					xmlStreamWriter.writeStartElement("quality");
					xmlStreamWriter.writeCharacters(String.valueOf(report.getQuality()));
					xmlStreamWriter.writeEndElement();

					xmlStreamWriter.writeStartElement("groups");
					for (String gr : report.getGroupsList()) {
						xmlStreamWriter.writeStartElement("group");
						xmlStreamWriter.writeCharacters(gr);
						xmlStreamWriter.writeEndElement();
					}
					xmlStreamWriter.writeEndElement();

					xmlStreamWriter.writeStartElement("project");

					xmlStreamWriter.writeStartElement("id");
					xmlStreamWriter.writeCharacters(header.getProjectUuid());
					xmlStreamWriter.writeEndElement();

					xmlStreamWriter.writeStartElement("name");
					xmlStreamWriter.writeCharacters(header.getProjectId());
					xmlStreamWriter.writeEndElement();

					xmlStreamWriter.writeEndElement();

					xmlStreamWriter.writeStartElement("summary");
					xmlStreamWriter.writeAttribute("actions", String.valueOf(testSummary[0].getActions()));
					xmlStreamWriter.writeAttribute("duration", String.valueOf(durationChart.getTotal()));
					xmlStreamWriter.writeAttribute("status", String.valueOf(testSummary[0].getStatus()));
					xmlStreamWriter.writeAttribute("suiteName", String.valueOf(testSummary[0].getSuiteName()));
					xmlStreamWriter.writeAttribute("testName", String.valueOf(testSummary[0].getTestName()));

					if (StringUtils.isNoneEmpty(summaryText)) {
						xmlStreamWriter.writeStartElement("data");
						xmlStreamWriter.writeCharacters(summaryText);
						xmlStreamWriter.writeEndElement();
					}

					if (testSummary[0].getErrors() != null && !testSummary[0].getErrors().isEmpty()) {
						xmlStreamWriter.writeStartElement("errors");
						for (TestError err : testSummary[0].getErrors()) {
							xmlStreamWriter.writeStartElement("error");
							xmlStreamWriter.writeAttribute("line", String.valueOf(err.getLine()));
							xmlStreamWriter.writeAttribute("script", String.valueOf(err.getScript()));
							xmlStreamWriter.writeAttribute("testErrorStatus", String.valueOf(err.getTestErrorStatus()));
							xmlStreamWriter.writeCharacters(err.getMessage());
							xmlStreamWriter.writeEndElement();
						}
						xmlStreamWriter.writeEndElement();
					}
					xmlStreamWriter.writeEndElement();

					xmlStreamWriter.writeStartElement("analytics");
					xmlStreamWriter.writeStartElement("charts");
					xmlStreamWriter.writeStartElement("actionsType");
					xmlStreamWriter.writeCharacters(actionsTypeChart.getBase64Chart());
					xmlStreamWriter.writeEndElement();


					xmlStreamWriter.writeEndElement();
					xmlStreamWriter.writeEndElement();

					final DocumentBuilder builder = factory.newDocumentBuilder();
					final Document document = builder.newDocument();

					xmlStreamWriter.writeEndElement(); //Write Script node close element

					final int[] loopAction = {0};
					((SimpleNsStreamWriter) xmlStreamWriter).wrapAsRawWriter().write(""); //Write Actions node start element

					amf3StreamWriter.readAndProcessStream(obj -> {
						if (obj instanceof VisualAction data) {
							actionsSortingOrder.stream().filter(aLong -> aLong < data.getTimeLine()).sorted(Comparator.comparing(aLong -> aLong, Comparator.nullsLast(Comparator.naturalOrder()))).forEach(aLong -> {
								visualActions.stream().filter(visualAction -> Objects.equals(visualAction.getTimeLine(), aLong)).findFirst().ifPresent(visualAction -> {
									writeAction(savePic, visualAction, logger, summaryText, document, xmlFolderPath, addCharts, loopAction, (SimpleNsStreamWriter) xmlStreamWriter);
									visualActions.remove(visualAction);
								});
								actionsSortingOrder.remove(aLong);
							}
									);
							if (data.getTimeLine() != 0) {
								writeAction(savePic, data, logger, summaryText, document, xmlFolderPath, addCharts, loopAction, (SimpleNsStreamWriter) xmlStreamWriter);
								actionsSortingOrder.remove(data.getTimeLine());
								loopAction[0]++;
							}
						}
					});

					if (!actionsSortingOrder.isEmpty()) {
						actionsSortingOrder.forEach(
								aLong -> {
									visualActions.stream().filter(visualAction -> Objects.equals(visualAction.getTimeLine(), aLong)).findFirst().ifPresent(visualAction -> {
										visualActions.remove(visualAction);
										writeAction(savePic, visualAction, logger, summaryText, document, xmlFolderPath, addCharts, loopAction, (SimpleNsStreamWriter) xmlStreamWriter);
									});
								}
								);
					}

					((SimpleNsStreamWriter) xmlStreamWriter).wrapAsRawWriter().write(""); //Write Actions node close element

					xmlStreamWriter.writeEndElement(); //Write Ats node close element
					xmlStreamWriter.writeEndDocument();
					xmlStreamWriter.close();
				}

			} catch (IOException | XMLStreamException e) {
				logger.sendError("XML report error ->", e.getMessage());
			} catch (ParserConfigurationException e) {
				throw new RuntimeException(e);
			}

			logger.sendInfo("XML report generated", xmlFolder.getAbsolutePath());
			
			if(cleanAtsv) {
				logger.sendInfo("clean atsv file", atsvFile.getAbsolutePath());
				atsvFile.delete();
			}

		} else { // No ATSV file found

			final File xmlFolder = output.resolve(qualifiedName + "_xml").toFile();
			logger.sendInfo("Create empty XML report because no ATSV file found", xmlFolder.getAbsolutePath());

			try {
				Utils.deleteRecursive(xmlFolder);
			} catch (FileNotFoundException e) {
			}

			xmlFolder.mkdirs();

			if (shadowScript != null) {

				try {

					final BufferedWriter writer = Files.newBufferedWriter(xmlFolder.toPath().resolve(REPORT_DATA_FILE), StandardCharsets.UTF_8);
					final Transformer transformer = TransformerFactory.newInstance().newTransformer();
					transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

					Element scriptXmlResult = shadowScript.getScriptXmlResult(summaryText);
					Node duration = scriptXmlResult.getChildNodes().item(0).getChildNodes().item(8).getAttributes().getNamedItem("duration");
					scriptXmlResult.setAttribute("devReportLVL", "0");
					scriptXmlResult.setAttribute("duration", duration == null ? "0" : duration.getTextContent());

					transformer.transform(new DOMSource(scriptXmlResult), new StreamResult(writer));

				} catch (TransformerConfigurationException e2) {
					logger.sendError("XML report config error ->", e2.getMessage());
				} catch (TransformerException e3) {
					logger.sendError("XML report transform error ->", e3.getMessage());
				} catch (FileNotFoundException e4) {
					logger.sendError("XML report write file error ->", e4.getMessage());
				} catch (IOException e5) {
					logger.sendError("XML report IO write file error ->", e5.getMessage());
				} catch (Throwable tr) {
					logger.sendError("XML report error ->", tr.getMessage());
				}
			}

			logger.sendInfo("XML report generated", xmlFolder.getAbsolutePath());
		}
		AtsLogger.printLog("data file generated -> " + (System.nanoTime() - dataFileGenerationStartTime) / 1000000000 + " second(s)");
	}

	private static void writeAction(boolean savePic, VisualAction data, ExecutionLogger logger, String summaryText, Document document, Path xmlFolderPath, boolean addCharts, int[] loopAction, SimpleNsStreamWriter xmlStreamWriter) {
		Element elem = data.getAction(logger, summaryText, document, xmlFolderPath, savePic, addCharts);
		if (elem != null) {
			try {
				elem.setAttribute("index", String.valueOf(loopAction[0]));
				String actionString = null;
				actionString = getElementString(elem);
				xmlStreamWriter.wrapAsRawWriter().write(actionString);
			} catch (TransformerException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@NotNull
	private static String getElementString(Element summaryElement) throws TransformerException {
		StringWriter stringWriter = new StringWriter();
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource domSource = new DOMSource(summaryElement);
		StreamResult streamResult = new StreamResult(stringWriter);
		transformer.transform(domSource, streamResult);
		String actionString = stringWriter.toString().replace("", "");
		return actionString;
	}

	public static Element readSummaryFile(DocumentBuilder builder, Path file) throws SAXException, IOException, ParserConfigurationException {

		Document document = builder.parse(file.toFile());
		document.getDocumentElement().normalize();

		return document.getDocumentElement();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy