
com.seleniumtests.core.runner.CustomTestNGCucumberRunner Maven / Gradle / Ivy
/**
* 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
© 2015 - 2025 Weber Informatics LLC | Privacy Policy