automation.library.reporting.adapter.TestSourcesModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of library-reporting-extent Show documentation
Show all versions of library-reporting-extent Show documentation
The 'reporting' library can be used in conjunction with the 'cucumber' library and automatically generates output reports (Extent 4) when running BDD based cucumber testing.
The newest version!
package automation.library.reporting.adapter;
import cucumber.api.event.TestSourceRead;
import gherkin.*;
import gherkin.ast.*;
import java.util.HashMap;
import java.util.Map;
/**
* A port of extent-framework/extentreports-cucumber4-adaptor (Apache 2.0 licensed) for Extent Framework
* Original source: https://github.com/extent-framework/extentreports-cucumber4-adapter/blob/master/src/main/java/com/aventstack/extentreports/cucumber/adapter/TestSourcesModel.java
*
* TestSourcesModel from Cucumber-JVM (MIT licensed)
* Original source: https://github.com/cucumber/cucumber-jvm/blob/master/core/src/main/java/cucumber/runtime/formatter/TestSourcesModel.java
*
*/
final class TestSourcesModel {
private final Map pathToReadEventMap = new HashMap();
private final Map pathToAstMap = new HashMap();
private final Map> pathToNodeMap = new HashMap>();
static Feature getFeatureForTestCase(AstNode astNode) {
while (astNode.parent != null) {
astNode = astNode.parent;
}
return (Feature) astNode.node;
}
static Background getBackgroundForTestCase(AstNode astNode) {
Feature feature = getFeatureForTestCase(astNode);
ScenarioDefinition backgound = feature.getChildren().get(0);
if (backgound instanceof Background) {
return (Background) backgound;
} else {
return null;
}
}
static ScenarioDefinition getScenarioDefinition(AstNode astNode) {
return astNode.node instanceof ScenarioDefinition ? (ScenarioDefinition) astNode.node : (ScenarioDefinition) astNode.parent.parent.node;
}
static boolean isScenarioOutlineScenario(AstNode astNode) {
return !(astNode.node instanceof ScenarioDefinition);
}
static boolean isBackgroundStep(AstNode astNode) {
return astNode.parent.node instanceof Background;
}
static String calculateId(AstNode astNode) {
Node node = astNode.node;
if (node instanceof ScenarioDefinition) {
return calculateId(astNode.parent) + ";" + convertToId(((ScenarioDefinition) node).getName());
}
if (node instanceof ExamplesRowWrapperNode) {
return calculateId(astNode.parent) + ";" + Integer.toString(((ExamplesRowWrapperNode) node).bodyRowIndex + 2);
}
if (node instanceof TableRow) {
return calculateId(astNode.parent) + ";" + Integer.toString(1);
}
if (node instanceof Examples) {
return calculateId(astNode.parent) + ";" + convertToId(((Examples) node).getName());
}
if (node instanceof Feature) {
return convertToId(((Feature) node).getName());
}
return "";
}
static String convertToId(String name) {
return name.replaceAll("[\\s'_,!]", "-").toLowerCase();
}
void addTestSourceReadEvent(String path, TestSourceRead event) {
pathToReadEventMap.put(path, event);
}
Feature getFeature(String path) {
if (!pathToAstMap.containsKey(path)) {
parseGherkinSource(path);
}
if (pathToAstMap.containsKey(path)) {
return pathToAstMap.get(path).getFeature();
}
return null;
}
ScenarioDefinition getScenarioDefinition(String path, int line) {
return getScenarioDefinition(getAstNode(path, line));
}
AstNode getAstNode(String path, int line) {
if (!pathToNodeMap.containsKey(path)) {
parseGherkinSource(path);
}
if (pathToNodeMap.containsKey(path)) {
return pathToNodeMap.get(path).get(line);
}
return null;
}
boolean hasBackground(String path, int line) {
if (!pathToNodeMap.containsKey(path)) {
parseGherkinSource(path);
}
if (pathToNodeMap.containsKey(path)) {
AstNode astNode = pathToNodeMap.get(path).get(line);
return getBackgroundForTestCase(astNode) != null;
}
return false;
}
String getKeywordFromSource(String uri, int stepLine) {
Feature feature = getFeature(uri);
if (feature != null) {
TestSourceRead event = getTestSourceReadEvent(uri);
String trimmedSourceLine = event.source.split("\n")[stepLine - 1].trim();
GherkinDialect dialect = new GherkinDialectProvider(feature.getLanguage()).getDefaultDialect();
for (String keyword : dialect.getStepKeywords()) {
if (trimmedSourceLine.startsWith(keyword)) {
return keyword;
}
}
}
return "";
}
private TestSourceRead getTestSourceReadEvent(String uri) {
if (pathToReadEventMap.containsKey(uri)) {
return pathToReadEventMap.get(uri);
}
return null;
}
String getFeatureName(String uri) {
Feature feature = getFeature(uri);
if (feature != null) {
return feature.getName();
}
return "";
}
private void parseGherkinSource(String path) {
if (!pathToReadEventMap.containsKey(path)) {
return;
}
Parser parser = new Parser(new AstBuilder());
TokenMatcher matcher = new TokenMatcher();
try {
GherkinDocument gherkinDocument = parser.parse(pathToReadEventMap.get(path).source, matcher);
pathToAstMap.put(path, gherkinDocument);
Map nodeMap = new HashMap();
AstNode currentParent = new AstNode(gherkinDocument.getFeature(), null);
for (ScenarioDefinition child : gherkinDocument.getFeature().getChildren()) {
processScenarioDefinition(nodeMap, child, currentParent);
}
pathToNodeMap.put(path, nodeMap);
} catch (ParserException e) {
// Ignore exceptions
}
}
private void processScenarioDefinition(Map nodeMap, ScenarioDefinition child, AstNode currentParent) {
AstNode childNode = new AstNode(child, currentParent);
nodeMap.put(child.getLocation().getLine(), childNode);
for (Step step : child.getSteps()) {
nodeMap.put(step.getLocation().getLine(), new AstNode(step, childNode));
}
if (child instanceof ScenarioOutline) {
processScenarioOutlineExamples(nodeMap, (ScenarioOutline) child, childNode);
}
}
private void processScenarioOutlineExamples(Map nodeMap, ScenarioOutline scenarioOutline, AstNode childNode) {
for (Examples examples : scenarioOutline.getExamples()) {
AstNode examplesNode = new AstNode(examples, childNode);
TableRow headerRow = examples.getTableHeader();
AstNode headerNode = new AstNode(headerRow, examplesNode);
nodeMap.put(headerRow.getLocation().getLine(), headerNode);
for (int i = 0; i < examples.getTableBody().size(); ++i) {
TableRow examplesRow = examples.getTableBody().get(i);
Node rowNode = new ExamplesRowWrapperNode(examplesRow, i);
AstNode expandedScenarioNode = new AstNode(rowNode, examplesNode);
nodeMap.put(examplesRow.getLocation().getLine(), expandedScenarioNode);
}
}
}
class ExamplesRowWrapperNode extends Node {
final int bodyRowIndex;
ExamplesRowWrapperNode(Node examplesRow, int bodyRowIndex) {
super(examplesRow.getLocation());
this.bodyRowIndex = bodyRowIndex;
}
}
class AstNode {
final Node node;
final AstNode parent;
AstNode(Node node, AstNode parent) {
this.node = node;
this.parent = parent;
}
}
}