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

com.seleniumtests.util.squashta.TaScriptGenerator Maven / Gradle / Ivy

There is a newer version: 4.23.18
Show newest version
/**
 * 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