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

com.seleniumtests.core.runner.CustomTestNGCucumberRunner 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
 * 				Copyright 2017-2019 B.Hecquet
 *
 * 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.core.runner;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FilenameUtils;

import com.seleniumtests.core.SeleniumTestsContextManager;
import com.seleniumtests.customexception.CustomSeleniumTestsException;

import cucumber.api.testng.FeatureResultListener;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.CucumberException;
import cucumber.runtime.Runtime;
import cucumber.runtime.RuntimeOptions;
import cucumber.runtime.RuntimeOptionsFactory;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;
import cucumber.runtime.model.CucumberExamples;
import cucumber.runtime.model.CucumberFeature;
import cucumber.runtime.model.CucumberScenario;
import cucumber.runtime.model.CucumberScenarioOutline;
import cucumber.runtime.model.CucumberTagStatement;
import cucumber.runtime.model.StepContainer;
import gherkin.formatter.Formatter;

public class CustomTestNGCucumberRunner {

	private Runtime runtime;
	private List cucumberFeatures;
    private RuntimeOptions runtimeOptions;
    private ResourceLoader resourceLoader;
    private FeatureResultListener resultListener;
    private ClassLoader classLoader;

    /**
     * Bootstrap the cucumber runtime
     *
     * @param clazz Which has the cucumber.api.CucumberOptions and org.testng.annotations.Test annotations
     */
    public CustomTestNGCucumberRunner(Class clazz) {
        classLoader = clazz.getClassLoader();
        resourceLoader = new MultiLoader(classLoader);
        
        cucumberFeatures = initCucumberOptions(clazz);

        resultListener = new FeatureResultListener(runtimeOptions.reporter(classLoader), runtimeOptions.isStrict());
    }
    
    private List initCucumberOptions(Class clazz) {
    	String cucumberPkg = SeleniumTestsContextManager.getGlobalContext().getCucmberPkg();
    	if (cucumberPkg == null) {
    		throw new CustomSeleniumTestsException("'cucumberPackage' parameter is not set in test NG XML file (inside  tag), "
    				+ "set it to the root package where cucumber implementation resides");
    	}
    	
    	// get all features, filtered by test name
    	System.setProperty("cucumber.options", "'" + SeleniumTestsContextManager.getFeaturePath() + "'");
        List testSelectedFeatures = getFeaturesFromRequestedTests(clazz, resourceLoader);

    	// build cucumber option list
        // take into account tag options
        String cucumberOptions = "";
        String tagList = SeleniumTestsContextManager.getThreadContext().getCucumberTags();
        if (tagList != null && !"".equals(tagList)) {
        	StringBuilder tagsOptions = new StringBuilder(" ");
        	for (String tags: tagList.split("AND")) {
        		tagsOptions.append(String.format("--tags %s ", tags.trim()));
        	}
        	
        	cucumberOptions += tagsOptions.toString();    	
        }
        
        // add cucumber implementation classes
        cucumberOptions += " --glue classpath:" + cucumberPkg;
        if (!cucumberPkg.startsWith("com.seleniumtests")) {
        	cucumberOptions += " --glue classpath:com.seleniumtests.core.runner.cucumber";
        }
        
        // add feature path
        cucumberOptions += " '" + SeleniumTestsContextManager.getFeaturePath() + "'";
        
        // correct issue #243: as we write to log files, colors cannot be rendered in text files
        cucumberOptions += " --monochrome";

        // get filtered features, based on tags
        runtimeOptions = new RuntimeOptions(cucumberOptions);
        ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
        runtime = new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);

        // add list of tag filtered features to features selected by tests 
        if (tagList != null && !"".equals(tagList)) {
        	testSelectedFeatures.addAll(runtimeOptions.cucumberFeatures(resourceLoader));
        }
         
        if (testSelectedFeatures.isEmpty()) {
        	throw new CustomSeleniumTestsException("No test has been selected");
        }
        
        return testSelectedFeatures;
    }
    
    /**
     * Get list of features given their name or their file name
     */
    private List getFeaturesFromRequestedTests(Class clazz, ResourceLoader resourceLoader) {

        RuntimeOptions runtimeOptionsB = new RuntimeOptionsFactory(clazz).create();
        
        final List allFeatures = runtimeOptionsB.cucumberFeatures(resourceLoader);
        List selectedFeatures = new ArrayList<>();
        
        // filter features requested for execution
        List testList = SeleniumTestsContextManager.getThreadContext().getCucumberTests();
        
        selectFeatures(allFeatures, selectedFeatures, testList);
        
        
        if (selectedFeatures.isEmpty()) {
        	// select scenarios in features
        	
            // get only scenarios whose name is in the list of tests
        	for (CucumberFeature feature: allFeatures) {
        		
        		List selectedScenarios = new ArrayList<>();
        		
        		selectSenario(feature, testList, selectedScenarios);
            				
        		feature.getFeatureElements().removeAll(feature.getFeatureElements());
        		feature.getFeatureElements().addAll(selectedScenarios);
        		
        		if (!selectedScenarios.isEmpty()) {
        			selectedFeatures.add(feature);
        		}
        	}
        }
        
        return selectedFeatures;
    }
    
    /**
     * 
     * @param allFeatures
     * @param selectedFeatures
     * @param testList
     * @return Cucumber feature list of selected tests
     */
    private List selectFeatures(final List allFeatures, List selectedFeatures, 
    									List testList){
    	for (CucumberFeature feature: allFeatures) {
        	String featureName = feature.getGherkinFeature().getName();
        	String featureFileName = FilenameUtils.getBaseName(feature.getPath());
        	
        	for (String test: testList) {
    			if (featureName.matches(test) || test.equals(featureFileName)) {
    				selectedFeatures.add(feature);
    				break;
    			}
    		}  
        }
    	return selectedFeatures;
    }
    
    /**
     * 
     * @param feature
     * @param testList
     * @param selectedScenarios
     * @return Cucumber statement list of selected tests
     */
    private List selectSenario(CucumberFeature feature, List testList, 
    													List selectedScenarios){
    	for (CucumberTagStatement stmt: feature.getFeatureElements()) {
			
			for (String test: testList) {
    			if (stmt.getGherkinModel().getName().equals(test) || stmt.getGherkinModel().getName().matches(test)) {
    				selectedScenarios.add(stmt);
    			}
			}
		}
    	return selectedScenarios;
    }

    public void runScenario(CucumberScenarioWrapper cucumberScenarioWrapper)   {
    	
    	resultListener.startFeature();
    	
    	Formatter formatter = runtimeOptions.formatter(classLoader);
    	CucumberScenario cucumberScenario = cucumberScenarioWrapper.getCucumberScenario();
    	
    	try {
	    	Field field = StepContainer.class.getDeclaredField("cucumberFeature");
			field.setAccessible(true);
			CucumberFeature cucumberFeature = (CucumberFeature)field.get(cucumberScenario);
	    	formatter.uri(cucumberFeature.getPath());
	        formatter.feature(cucumberFeature.getGherkinFeature());
	    	
	    	cucumberScenario.run(runtimeOptions.formatter(classLoader), resultListener, runtime);
	    	formatter.eof();
    	} catch (NoSuchFieldException | IllegalAccessException e) {
    		throw new CucumberException("Could not run scenario: " + e.getMessage());
    	}
    	
    	if (!resultListener.isPassed()) {
            throw new CucumberException(resultListener.getFirstError());
        }
    }

    public void finish() {
        Formatter formatter = runtimeOptions.formatter(classLoader);
        formatter.done();
        formatter.close();
        runtime.printSummary();
        if (!runtime.getSnippets().isEmpty()) {
        	throw new CucumberException("Some steps could not be found");
        }
    }

    /**
     * @return List of detected cucumber features
     */
    public List getFeatures() {
        return cucumberFeatures;
    }
	
	public Object[][] provideScenarios() {
		List scenarioList = new ArrayList<>();
        for (CucumberFeature feature : getFeatures()) {
        	
        	// get scenario / scenario outline
        	for (CucumberTagStatement cucumberTagStatement : feature.getFeatureElements()) {
                
        		getScenarioWrapper(cucumberTagStatement, scenarioList);
            }
       }
        
       List newScenarioList = new ArrayList<>();
       for (CucumberScenarioWrapper scenarioWrapper: scenarioList) {
    	   newScenarioList.add(new Object[]{scenarioWrapper});
       }
        
       return newScenarioList.toArray(new Object[][]{});
    }
	
	/**
	 * 
	 * @param cucumberTagStatement
	 * @param scenarioList
	 * @return list of cucumber scenario wrapper
	 */
	private List getScenarioWrapper(CucumberTagStatement cucumberTagStatement, 
															List scenarioList){
		if (cucumberTagStatement instanceof CucumberScenarioOutline) {
			for (CucumberExamples cucumberExamples : ((CucumberScenarioOutline)cucumberTagStatement).getCucumberExamplesList()) {
	            for (CucumberScenario exampleScenario : cucumberExamples.createExampleScenarios()) {
        			CucumberScenarioWrapper scenarioWrapper = new CucumberScenarioWrapper(exampleScenario, cucumberTagStatement.getGherkinModel().getName());
	            	scenarioList.add(scenarioWrapper);
	            }
	        }
		} else {
			CucumberScenarioWrapper scenarioWrapper = new CucumberScenarioWrapper((CucumberScenario)cucumberTagStatement);
			if (!scenarioList.contains(scenarioWrapper)) {
				scenarioList.add(scenarioWrapper);
			}
		}
		return scenarioList;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy