com.seleniumtests.util.squashta.TaScriptGenerator Maven / Gradle / Ivy
/**
* Orignal work: Copyright 2015 www.seleniumtests.com
* Modified work: Copyright 2016 www.infotel.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.seleniumtests.util.squashta;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.filter.ElementFilter;
import org.jdom2.input.SAXBuilder;
import com.seleniumtests.util.logging.SeleniumRobotLogger;
public class TaScriptGenerator {
private static final Logger logger = SeleniumRobotLogger.getLogger(TaScriptGenerator.class);
private String srcPath;
private String dstPath;
private String application;
// patterns for exclusion from .ta script generation
private static final String XML_EXCLUDE = "EXCLUDE_FROM_SQUASH_TA";
private static final String FEATURE_EXCLUDE = "@EXCLUDE_FROM_SQUASH_TA";
/**
*
* @param srcPath Path to root of the test application. it's the location of the "data" folder
* @param dstPath Path to root where files will be written
* @param application name of the application
*/
public TaScriptGenerator(String application, String srcPath, String dstPath) {
this.srcPath = srcPath.replace("\\", "/");
this.dstPath = dstPath.replace("\\", "/");
this.application = application;
}
/**
* Search for scenarios in feature files
* @param path
* @param application
* @return
*/
public List parseFeatures() {
Pattern scenarioPattern = Pattern.compile("^\\s*Scenario:(.*)");
Pattern scenarioOutlinePattern = Pattern.compile("^\\s*Scenario Outline:(.*)");
// look for feature file into data folder
File dir = Paths.get(srcPath, "data", application, "features").toFile();
if (!dir.exists()) {
return new ArrayList<>();
}
File[] featureFiles = dir.listFiles((d, filename) -> filename.endsWith(".feature"));
List scenarios = new ArrayList<>();
for (File featureFile: featureFiles) {
try {
boolean exclude = false;
for (String line: FileUtils.readLines(featureFile, "UTF-8")) {
// exclude scenarios using tag @EXCLUDE_FROM_SQUASH_TA
if (line.contains(FEATURE_EXCLUDE)) {
exclude = true;
}
Matcher matcher = scenarioPattern.matcher(line);
if (matcher.matches()) {
if (!exclude) {
scenarios.add(matcher.group(1).trim());
}
exclude = false;
}
Matcher matcherOutline = scenarioOutlinePattern.matcher(line);
if (matcherOutline.matches()) {
if (!exclude) {
scenarios.add(matcherOutline.group(1).trim());
}
exclude = false;
}
}
} catch (IOException e) {
// ignore
}
}
return scenarios;
}
/**
* Read a test element in an XML testNG file
* @param test the test element to read
* @param testDefs list of test definitions to update
* @param testngFile testNgFile read
*/
private void readTestTag(Element test, List testDefs, File testngFile) {
boolean cucumberTest = false;
String cucumberNamedTest = "";
boolean exclude = false;
// search cucumber parameters among test parameters
// does test specifies precise cucumber properties (cucumberTests / cucumberTags)
for (Element param: test.getChildren("parameter")) {
if ("cucumberTests".equals(param.getAttributeValue("name"))) {
cucumberTest = true;
cucumberNamedTest = param.getAttributeValue("value");
if (!cucumberNamedTest.isEmpty()) {
break;
}
}
else if ("cucumberTags".equals(param.getAttributeValue("name"))) {
cucumberTest = true;
cucumberNamedTest = param.getAttributeValue("value");
if (!cucumberNamedTest.isEmpty()) {
break;
}
}
}
for (Element param: test.getChildren("parameter")) {
if (XML_EXCLUDE.equals(param.getAttributeValue("name"))) {
exclude = true;
}
}
// is this test a cucumber test ? (calling specific runner)
for (Element pack: test.getDescendants(new ElementFilter("package"))) {
if (pack.getAttributeValue("name").contains("com.seleniumtests.core.runner")) {
cucumberTest = true;
}
}
if (!exclude) {
if (cucumberTest) {
testDefs.add(new SquashTaTestDef(testngFile, test.getAttributeValue("name"), true, cucumberNamedTest));
} else {
testDefs.add(new SquashTaTestDef(testngFile, test.getAttributeValue("name"), false, ""));
}
}
}
/**
* Search for tests in TestNG files
* @param path
* @param application
* @return
*/
public List parseTestNgXml() {
// look for feature file into data folder
File dir = Paths.get(srcPath, "data", application, "testng").toFile();
if (!dir.exists()) {
return new ArrayList<>();
}
File[] testngFiles = dir.listFiles((d, filename) -> filename.endsWith(".xml"));
List testDefs = new ArrayList<>();
for (File testngFile: testngFiles) {
Document doc;
SAXBuilder sxb = new SAXBuilder();
sxb.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
try {
doc = sxb.build(testngFile);
}
catch(Exception e){
logger.error(String.format("Fichier %s illisible: %s", testngFile, e.getMessage()));
return testDefs;
}
Element suite = doc.getRootElement();
if (!"suite".equalsIgnoreCase(suite.getName())) {
continue;
}
for (Element test: suite.getChildren("test")) {
readTestTag(test, testDefs, testngFile);
}
}
return testDefs;
}
/**
* Remove all .ta files which are present in folder but have not been generated by this run
* e.g: xml files which may have disapear or some test that have been excluded from Squash TA generation
*/
public void cleanGeneratedFile(String taScriptDir, List generatedTaFileList) {
// get .ta files
File dir = new File(taScriptDir);
File[] taFiles = dir.listFiles((d, filename) -> filename.endsWith(".ta"));
List taFileNames = new ArrayList<>();
for (String generatedTaFile: generatedTaFileList) {
taFileNames.add(new File(generatedTaFile).getName());
}
for (File file: taFiles) {
if (!taFileNames.contains(file.getName()) && file.getName().startsWith("g__")) {
logger.info("deleting " + file);
file.delete();
}
}
}
/**
* Generate .ta scripts based on the generic one
* $cucumberTest$ pattern replaced by -DcucumberTest=
* $testngFile$ pattern replaced by the test ng file path. It's a path beginning with %STF_HOME% so that
* it uses env variables
* $testngName$ pattern replaced by name of the testng test
* @throws IOException
*/
public void generateTaScripts() throws IOException {
String taScriptDir = Paths.get(dstPath, "src", "squashTA", "tests").toString();
File srcTaFile = Paths.get(srcPath, "data", application, "squash-ta", "src", "squashTA", "tests", application + "_generic.ta").toFile();
File genericFile = new File(taScriptDir + File.separator + application + "_generic.ta");
if (srcTaFile.exists()) {
try {
FileUtils.copyFile(srcTaFile, genericFile);
} catch (IOException e) {
logger.warn("Cannot copy file: " + e.getMessage());
}
}
// if base script does not exist, skip script generation
if (!genericFile.exists()) {
return;
}
String content = FileUtils.readFileToString(genericFile);
// generate .ta files
List cucumberScenarios = parseFeatures();
List testNgTests = parseTestNgXml();
List taFileList = new ArrayList<>();
for (SquashTaTestDef testDef: testNgTests) {
if (testDef.isCucumber && testDef.isCucumberGeneric) {
for (String cucumberScenario: cucumberScenarios) {
String newContent = content
.replace("$cucumberTest$", String.format("-DcucumberTests\"=%s\"", cucumberScenario.replace(" ", " ")))
.replace("$testngFile$", testDef.file.getAbsolutePath()
.replace("\\", "/")
.replace(srcPath, "%STF_HOME%/"))
.replace("$testngName$", testDef.name)
.replace("$app$", application);;
String fileName = String.format("g__%s_%s_%s.ta", testDef.file.getName(), testDef.name, cucumberScenario
.replace(" ", "_")
.replace("<", "")
.replace(">", ""));
FileUtils.writeStringToFile(new File(taScriptDir + File.separator + fileName), newContent, "UTF-8");
taFileList.add(fileName);
logger.info("generating " + taScriptDir + File.separator + fileName);
}
} else {
String newContent = content
.replace("$cucumberTest$", "")
.replace("$testngFile$", testDef.file.getAbsolutePath()
.replace("\\", "/")
.replace(srcPath, "%STF_HOME%/"))
.replace("$testngName$", testDef.name)
.replace("$app$", application);;
String fileName = String.format("g__%s_%s.ta", testDef.file.getName(), testDef.name);
FileUtils.writeStringToFile(new File(taScriptDir + File.separator + fileName), newContent, "UTF-8");
taFileList.add(fileName);
logger.info("generating " + taScriptDir + File.separator + fileName);
}
}
cleanGeneratedFile(taScriptDir, taFileList);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy