/*
* Copyright (c) 2010-2011 Ardesco Solutions - http://www.ardescosolutions.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lazerycode.ebselen;
import com.lazerycode.ebselen.handlers.FileHandler;
import com.lazerycode.ebselen.handlers.XMLHandler;
import java.io.File;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.Properties;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.PrettyXmlSerializer;
import org.htmlcleaner.TagNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IDEToEbselen {
public static final Logger LOGGER = LoggerFactory.getLogger(IDEToEbselen.class);
private boolean walkTree;
private String startPoint;
private String testCode = "";
private ArrayList<String> fileList = new ArrayList<String>();
private CreateTestCode codeGenerator = new CreateTestCode();
private final String ebselenTestTemplate = "/templates/template.vm";
private final String conversionLocation = "ebselen-tests/src/test/java/com/lazerycode/ebselen/website/convertedfromide"; //.replaceAll("/", File.separator);
public IDEToEbselen(String value, boolean doWalkTree) throws Exception {
walkTree = doWalkTree;
startPoint = value;
createFileList();
convertFileList();
}
private void addToTestCode(String value) {
testCode += value + ";\n";
}
/**
* Cleans the relevant file and generates a valid XML file ready for processing to Sel 2 java File.
*
* @param absoluteFilename - name of the file to convert.
* @return String - location of the converted file.
*/
public String convertToXML(String absoluteFilename) throws Exception {
FileHandler fromSelIDE = new FileHandler(absoluteFilename);
FileHandler toXML = new FileHandler(System.getProperty("java.io.tmpdir") + File.separator + fromSelIDE.getFileName() + ".xml", true);
if (fromSelIDE.getFile().isDirectory()) {
LOGGER.error("Cannot convert directory {} into a Selenium Test!", fromSelIDE.getFileName());
return null;
}
//Clean up html so that we can read it as XML properly
HtmlCleaner cleaner = new HtmlCleaner();
CleanerProperties XMLPrefs = cleaner.getProperties();
XMLPrefs.setUseEmptyElementTags(true);
XMLPrefs.setTranslateSpecialEntities(true);
XMLPrefs.setTransResCharsToNCR(true);
XMLPrefs.setOmitComments(true);
XMLPrefs.setOmitComments(true);
XMLPrefs.setOmitDoctypeDeclaration(true);
XMLPrefs.setNamespacesAware(false);
TagNode tagNode = new HtmlCleaner(XMLPrefs).clean(fromSelIDE.getFile());
new PrettyXmlSerializer(XMLPrefs).writeToStream(tagNode, toXML.getWritableFileOutputStream(), "utf-8");
toXML.close();
return toXML.getAbsoluteFile();
}
/**
* Traverse directory and create a list of all the files that need to be converted
*/
public void createFileList() throws Exception {
FileHandler checkFileType = new FileHandler(startPoint);
if (!checkFileType.getFile().isDirectory()) {
LOGGER.error("The file '{}' is not a directory, will only try to convert this file...", checkFileType.getFileName());
if (checkFileType.getFile().isFile()) {
fileList.add(checkFileType.getFilePath() + checkFileType.getFileName());
}
checkFileType.close();
return;
}
checkFileType.close();
LOGGER.error("Scanning all files in the directory '{}'...", checkFileType.getFileName());
ArrayList scanList = new ArrayList();
scanList.add(startPoint);
while (scanList.size() > 0) {
FileHandler directoryToScan = new FileHandler(scanList.get(0).toString());
File[] listOfFiles = directoryToScan.getFile().listFiles();
for (File currentFile : listOfFiles) {
FileHandler examineFile = new FileHandler(currentFile.getAbsolutePath());
if (!examineFile.getExtension().equals("java")) {
if (examineFile.getFile().isFile()) {
fileList.add(examineFile.getFilePath() + examineFile.getFileName());
} else if (examineFile.getFile().isDirectory()) {
if (walkTree) {
scanList.add(currentFile);
}
}
}
examineFile.close();
}
directoryToScan.close();
scanList.remove(0);
}
}
/**
* Iterate through a list of files converting them to Ebselen implementation tests
*
* @throws Exception
*/
public void convertFileList() throws Exception {
for (String file : fileList) {
generateJavaFile(generateTestCode(file));
}
}
/**
* Reads in a sky.sns.selenium IDE file and creates Sky Selenium format test code
*
* @param filename - Selenium IDE file to convert
* @return Name of the Selenium IDE file
* @throws Exception
*/
public String generateTestCode(String filename) throws Exception {
FileHandler convertFrom = new FileHandler(convertToXML(filename));
XMLHandler seleniumXMLFile = new XMLHandler(convertFrom.getFile());
int commandCount = seleniumXMLFile.performXPathQueryReturnInteger("count(/html/body/table/tbody/tr)");
for (int i = 1; i <= commandCount; i++) {
String command = "";
String target = "";
String value = "";
try {
command = seleniumXMLFile.performXPathQueryReturnString("//table/tbody/tr[" + i + "]/td[1]");
target = seleniumXMLFile.performXPathQueryReturnString("/html/body/table/tbody/tr[" + i + "]/td[2]");
value = seleniumXMLFile.performXPathQueryReturnString("/html/body/table/tbody/tr[" + i + "]/td[3]");
} catch (Exception Ex) {
LOGGER.warn("Invalid command '{}' found", command);
}
addToTestCode(codeGenerator.convertCommandToEbselenCode(command, target, value));
}
convertFrom.close();
return convertFrom.getFileName().split("\\.")[0];
}
/**
* Writes Sky Selenium format test code into a Java file ready for tests to be run
*
* @param name - Name of the test
* @throws Exception
*/
public void generateJavaFile(String name) throws Exception {
Properties props = new Properties();
props.setProperty("resource.loader", "class");
props.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
props.setProperty("class.resource.loader.description", "Velocity Classpath Resource Loader");
VelocityEngine ve = new VelocityEngine(props);
VelocityContext context = new VelocityContext();
context.put("template", name);
context.put("templateclass", name + ".class");
context.put("testname", name);
context.put("testdata", testCode);
Template ebselenTemplate = ve.getTemplate(ebselenTestTemplate);
FileHandler convertedFile = new FileHandler(conversionLocation + File.separator + name + ".java", true);
StringWriter writer = new StringWriter();
ebselenTemplate.merge(context, writer);
convertedFile.write(writer.toString());
convertedFile.close();
LOGGER.info("Selenium IDE test converted and saved as '" + convertedFile.getFilePath() + convertedFile.getFileName() + "'");
}
public static void main(String[] args) throws Exception {
boolean walkDirectories = false;
if (null == args || args.length < 1) {
LOGGER.error("Invalid argument set passed!\n" +
"Arguments required are:\n\n" +
"[0] String filename - File or directory full of files to convert.\n" +
"[1] Boolean true/false - if above is a directory traverse child directories as well.\n" +
"\n");
System.exit(1);
} else {
if (args.length > 2) {
LOGGER.info("More than 2 arguments detected, the first two will be used and the rest will be ignored.");
}
if (args.length > 1) {
walkDirectories = Boolean.parseBoolean(args[1].toString());
}
new IDEToEbselen(args[0], walkDirectories);
}
}
}