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

com.qmetry.qaf.automation.cucumber.QAFCucumberPlugin Maven / Gradle / Ivy

Go to download

Functional test automation framework for web, mobile-web, mobile native and web-service

There is a newer version: 4.0.0-RC3
Show newest version
/**
 * 
 */
package com.qmetry.qaf.automation.cucumber;

import static com.qmetry.qaf.automation.core.ConfigurationManager.getBundle;
import static com.qmetry.qaf.automation.data.MetaDataScanner.*;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import com.qmetry.qaf.automation.core.AutomationError;
import com.qmetry.qaf.automation.core.CheckpointResultBean;
import com.qmetry.qaf.automation.core.LoggingBean;
import com.qmetry.qaf.automation.core.MessageTypes;
import com.qmetry.qaf.automation.core.QAFTestBase;
import com.qmetry.qaf.automation.core.TestBaseProvider;
import com.qmetry.qaf.automation.integration.ResultUpdator;
import com.qmetry.qaf.automation.integration.TestCaseResultUpdator;
import com.qmetry.qaf.automation.integration.TestCaseRunResult;
import com.qmetry.qaf.automation.keys.ApplicationProperties;
import com.qmetry.qaf.automation.util.ClassUtil;
import com.qmetry.qaf.automation.util.Reporter;
import com.qmetry.qaf.automation.util.StringMatcher;
import com.qmetry.qaf.automation.util.StringUtil;

import io.cucumber.plugin.ConcurrentEventListener;
import io.cucumber.plugin.event.EmbedEvent;
import io.cucumber.plugin.event.EventHandler;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.PickleStepTestStep;
import io.cucumber.plugin.event.Result;
import io.cucumber.plugin.event.Status;
import io.cucumber.plugin.event.TestCase;
import io.cucumber.plugin.event.TestCaseFinished;
import io.cucumber.plugin.event.TestCaseStarted;
import io.cucumber.plugin.event.TestRunFinished;
import io.cucumber.plugin.event.TestRunStarted;
import io.cucumber.plugin.event.TestStepFinished;
import io.cucumber.plugin.event.TestStepStarted;
import io.cucumber.plugin.event.WriteEvent;

/**
 * This is cucumber plugin need to be used when Cucumber runner is used. It will
 * generate QAF JSON reports.
 * 
 * @author chirag.jayswal
 *
 */
public class QAFCucumberPlugin implements ConcurrentEventListener {
	private static final Log logger = LogFactoryImpl.getLog(QAFCucumberPlugin.class);

	/*
	 * (non-Javadoc)
	 * 
	 * @s() { }ee
	 * io.cucumber.plugin.ConcurrentEventListener#setEventPublisher(io.cucumber.
	 * plugin.event.EventPublisher)
	 */
	@Override
	public void setEventPublisher(EventPublisher publisher) {
		setCucumberRunner(true);

		publisher.registerHandlerFor(TestRunStarted.class, runStartedHandler);
		publisher.registerHandlerFor(TestRunFinished.class, runFinishedHandler);

		publisher.registerHandlerFor(TestCaseStarted.class, tcStartedHandler);
		publisher.registerHandlerFor(TestCaseFinished.class, tcfinishedHandler);

		publisher.registerHandlerFor(TestStepStarted.class, stepStartedHandler);
		publisher.registerHandlerFor(TestStepFinished.class, stepfinishedHandler);
		publisher.registerHandlerFor(EmbedEvent.class, embedEventHandler);
		publisher.registerHandlerFor(WriteEvent.class, (event) -> {
			Reporter.log(event.getText());
		});

	}

	private EventHandler embedEventHandler = new EventHandler() {

		@Override
		public void receive(EmbedEvent event) {
			// event.
		}
	};

	private EventHandler stepStartedHandler = new EventHandler() {

		@Override
		public void receive(TestStepStarted event) {
			// TestStep step = event.getTestStep();
			QAFTestBase stb = TestBaseProvider.instance().get();
			ArrayList allResults = new ArrayList(
					stb.getCheckPointResults());
			ArrayList allCommands = new ArrayList(stb.getLog());
			stb.getCheckPointResults().clear();
			stb.getLog().clear();
			stb.getContext().setProperty("allResults", allResults);
			stb.getContext().setProperty("allCommands", allCommands);

		}
	};
	private EventHandler stepfinishedHandler = new EventHandler() {

		@Override
		public void receive(TestStepFinished event) {
			if (event.getTestStep() instanceof PickleStepTestStep) {
				logStep((PickleStepTestStep) event.getTestStep(), event);
			}
		}

		@SuppressWarnings("unchecked")
		private void logStep(PickleStepTestStep testStep, TestStepFinished event) {
			;
			Result result = event.getResult();
			String stepText = testStep.getStep().getKeyWord() + testStep.getStepText();
			Long duration = result.getDuration().toMillis();
			QAFTestBase stb = TestBaseProvider.instance().get();

			if (result.getError() != null) {
				CheckpointResultBean failureCheckpoint = new CheckpointResultBean();
				failureCheckpoint.setMessage(result.getError().getMessage());
				failureCheckpoint.setType(MessageTypes.Fail);
				stb.getCheckPointResults().add(failureCheckpoint);
			}
			if(result.getStatus().is(Status.UNDEFINED)) {
				stepText = stepText+": Not Found";
				stb.addVerificationError(event.getTestStep().getCodeLocation() + "TestStep implementation not found");
			}

			MessageTypes type = result.getStatus().is(Status.PASSED)
					&& getStepMessageType(stb.getCheckPointResults()).isFailure() ? MessageTypes.TestStepFail
							: getStepMessageType(result.getStatus(), isDryRun(event.getTestCase()));
			// MessageTypes type = success? getStepMessageType(stb.getCheckPointResults()) :
			// MessageTypes.;

			LoggingBean stepLogBean = new LoggingBean(testStep.getPattern(),
					testStep.getDefinitionArgument().stream().map(a -> {
						return a.getValue();
					}).collect(Collectors.toList()).toArray(new String[] {}), result.getStatus().name());
			stepLogBean.setSubLogs(new ArrayList(stb.getLog()));

			CheckpointResultBean stepResultBean = new CheckpointResultBean();
			stepResultBean.setMessage(stepText);
			stepResultBean.setSubCheckPoints(new ArrayList(stb.getCheckPointResults()));
			stepResultBean.setDuration(duration.intValue());

			stepResultBean.setType(type);

			ArrayList allResults = (ArrayList) stb.getContext()
					.getObject("allResults");
			ArrayList allCommands = (ArrayList) stb.getContext().getObject("allCommands");
			stb.getContext().clearProperty("allResults");
			stb.getContext().clearProperty("allCommands");

			allResults.add(stepResultBean);

			stb.getCheckPointResults().clear();
			stb.getCheckPointResults().addAll(allResults);

			allCommands.add(stepLogBean);
			stb.getLog().clear();
			stb.getLog().addAll(allCommands);
		}

		private MessageTypes getStepMessageType(List subSteps) {
			MessageTypes type = MessageTypes.TestStepPass;
			for (CheckpointResultBean subStep : subSteps) {
				type = MessageTypes.TestStepPass;
				if (StringMatcher.containsIgnoringCase("fail").match(subStep.getType())) {
					return MessageTypes.TestStepFail;
				}
				if (StringMatcher.containsIgnoringCase("warn").match(subStep.getType())) {
					type = MessageTypes.Warn;
				}
			}
			return type;
		}

		private MessageTypes getStepMessageType(io.cucumber.plugin.event.Status status, boolean isDryRun) {
			switch (status) {
			case PASSED:
				return MessageTypes.TestStepPass;
			case FAILED:
			case UNDEFINED:
				return MessageTypes.TestStepFail;
			case AMBIGUOUS:
				return MessageTypes.Warn;
			default:
				if (isDryRun) {
					return MessageTypes.TestStepPass;
				}
				return MessageTypes.TestStep;
			}
		}
	};

	private EventHandler tcStartedHandler = new EventHandler() {

		@Override
		public void receive(TestCaseStarted event) {
			Bdd2Pickle bdd2Pickle = getBdd2Pickle(event.getTestCase());
			bdd2Pickle.getMetaData().put("Referece", event.getTestCase().getUri());
			QAFTestBase stb = TestBaseProvider.instance().get();
			stb.getLog().clear();
			stb.clearVerificationErrors();
			stb.getCheckPointResults().clear();
		}
	};

	private boolean isDryRun(TestCase tc) {
		return (boolean) getField("dryRun", tc);
	}

	private EventHandler tcfinishedHandler = new EventHandler() {

		@Override
		public void receive(TestCaseFinished event) {
			try {
				TestCase tc = event.getTestCase();
				Bdd2Pickle bdd2Pickle = getBdd2Pickle(tc);
				boolean isDryRun = isDryRun(tc);
				Result result = event.getResult();

				Throwable throwable = result.getError();
				QAFTestBase stb = TestBaseProvider.instance().get();

				if (isDryRun) {
					Map metadata = new HashMap(bdd2Pickle.getMetaData());
					if (null != bdd2Pickle.getTestData()) {
						metadata.putAll(bdd2Pickle.getTestData());
					}
					String vresult = applyMetaRule(metadata);
					if (StringUtil.isNotBlank(vresult)) {
						throwable = new AutomationError("Metadata rule failure:" + vresult);
						stb.addVerificationError(throwable);
					}
				}
				final List checkpoints = new ArrayList(
						stb.getCheckPointResults());
				final List logs = new ArrayList(stb.getLog());

				if (stb.getVerificationErrors() > 0 && (result.getStatus().is(Status.PASSED)||isDryRun)) {
					
					result = new Result(null!=throwable?result.getStatus():Status.FAILED, result.getDuration(), throwable);
					try {
						ClassUtil.setField("result", event, result);
					} catch (Exception e) {
					}
				}else if(isDryRun && (null==throwable)) {
					result = new Result(Status.PASSED, result.getDuration(), throwable);
					try {
						ClassUtil.setField("result", event, result);
					} catch (Exception e) {
					}
				}
				QAFReporter.createMethodResult(tc, bdd2Pickle, result, logs, checkpoints);
				if (!isDryRun) {
					deployResult(bdd2Pickle, tc, result);
				}
				String useSingleSeleniumInstance = getBundle().getString("selenium.singletone", "");
				if (useSingleSeleniumInstance.toUpperCase().startsWith("M")) {
					stb.tearDown();
				}
			} catch (Exception e) {
				logger.error("QAFCucumberPlugin unable to process TestCaseFinished event", e);
			}
		}

		private void deployResult(Bdd2Pickle bdd2Pickle, TestCase tc, Result eventresult) {
			String updator = getBundle().getString("result.updator");
			try {
				if (StringUtil.isNotBlank(updator)) {
					TestCaseRunResult result = eventresult.getStatus() == Status.PASSED ? TestCaseRunResult.PASS
							: eventresult.getStatus() == Status.FAILED ? TestCaseRunResult.FAIL
									: TestCaseRunResult.SKIPPED;

					// String method = testCase.getName();
					Class updatorCls = Class.forName(updator);

					TestCaseResultUpdator updatorObj = (TestCaseResultUpdator) updatorCls.newInstance();
					Map params = new TreeMap(String.CASE_INSENSITIVE_ORDER);

					params.put("name", tc.getName());
					params.put("duration", eventresult.getDuration().toMillis());

					// Bdd2Pickle bdd2Pickle = getBdd2Pickle(event.getTestCase());
					if (null != bdd2Pickle && null != bdd2Pickle.getMetaData()) {
						params.putAll(bdd2Pickle.getMetaData());
						Map testData = bdd2Pickle.getTestData();
						if (testData != null) {
							params.put("testdata", testData);
							String identifierKey = ApplicationProperties.TESTCASE_IDENTIFIER_KEY
									.getStringVal("testCaseId");
							if (testData.containsKey(identifierKey)) {
								params.put(identifierKey, testData.get(identifierKey));
							}
						}
					}

					QAFTestBase testBase = TestBaseProvider.instance().get();
					ResultUpdator.updateResult(result, testBase.getHTMLFormattedLog() + testBase.getAssertionsLog(),
							updatorObj, params);
				}
			} catch (Exception e) {
				logger.warn("QAFCucumberPlugin unable to deploy result", e);
			}
		}
	};

	private EventHandler runStartedHandler = new EventHandler() {
		@Override
		public void receive(TestRunStarted event) {
			startReport(event);
		}

		private void startReport(TestRunStarted event) {
			QAFReporter.createMetaInfo();
		}
	};
	private EventHandler runFinishedHandler = new EventHandler() {
		@Override
		public void receive(TestRunFinished event) {
			endReport(event);
		}

		private void endReport(TestRunFinished event) {
			QAFReporter.updateMetaInfo();
			QAFReporter.updateOverview(null, true);
			;

			TestBaseProvider.instance().stopAll();
			ResultUpdator.awaitTermination();
		}
	};

	private static Bdd2Pickle getBdd2Pickle(Object testCase) {
		try {
			Object pickle = getField("pickle", testCase);
			if (pickle instanceof Bdd2Pickle) {
				return ((Bdd2Pickle) pickle);
			} else {
				return getBdd2Pickle(pickle);
			}
		} catch (Exception e) {
			return null;
		}
	}

	public static Object getField(String fieldName, Object classObj) {
		try {

			Field field = null;
			try {
				field = classObj.getClass().getField(fieldName);
			} catch (NoSuchFieldException e) {
				Field[] fields = ClassUtil.getAllFields(classObj.getClass(), Object.class);
				for (Field f : fields) {
					if (f.getName().equalsIgnoreCase(fieldName)) {
						field = f;
						break;
					}
				}
			}

			field.setAccessible(true);
			Field modifiersField = Field.class.getDeclaredField("modifiers");
			modifiersField.setAccessible(true);
			modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
			return field.get(classObj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private void setCucumberRunner(boolean cucumberRunner) {
		getBundle().setProperty("cucumber.run.mode", cucumberRunner);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy