Skip to content

Commit

Permalink
Feature/cucumber4 plugin (#11)
Browse files Browse the repository at this point in the history
* Implement adaptor for Cucumber 4

* Increase version

* Fix Sonar issue
  • Loading branch information
paveliam authored Jun 3, 2020
1 parent 2ac3314 commit 4f59f7b
Show file tree
Hide file tree
Showing 13 changed files with 284 additions and 27 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ To use this adaptor with Cucumber 5 you have to add the following dependency:

Also you have to add plugin `aquality.tracking.integrations.cucumber5jvm.AqualityTrackingCucumber5Jvm` to the Cucumber Test Runner.

## Cucumber 4 [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.aquality-automation/aquality-tracking-cucumber4-jvm/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.aquality-automation/aquality-tracking-cucumber4-jvm)

To use this adaptor with Cucumber 4 you have to add the following dependency:

```xml
<dependency>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-tracking-cucumber4-jvm</artifactId>
<version>$LATEST_VERSION</version>
</dependency>
```

Also you have to add plugin `aquality.tracking.integrations.cucumber4jvm.AqualityTrackingCucumber4Jvm` to the Cucumber Test Runner.

#### How to increase version for all modules

```bash
Expand Down
63 changes: 63 additions & 0 deletions aquality-tracking-cucumber4-jvm/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<artifactId>aquality-tracking-cucumber4-jvm</artifactId>
<version>1.2.0</version>
<packaging>jar</packaging>

<parent>
<artifactId>aquality-tracking-integrations</artifactId>
<groupId>com.github.aquality-automation</groupId>
<version>1.2.0</version>
</parent>

<name>Aquality Tracking Cucumber 5 JVM</name>
<description>Aquality Tracking integration for Cucumber 5 JVM.</description>
<url>https://github.com/aquality-automation/aquality-tracking-integrations-java</url>

<dependencies>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.8.1</version>
</dependency>

<dependency>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-tracking-integrations-core</artifactId>
<version>1.2.0</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package aquality.tracking.integrations.cucumber4jvm;

import aquality.tracking.integrations.core.AqualityTrackingLifecycle;
import cucumber.api.event.*;

import java.util.UUID;

import static java.lang.String.format;

public class AqualityTrackingCucumber4Jvm implements ConcurrentEventListener {

private final AqualityTrackingLifecycle lifecycle;

public AqualityTrackingCucumber4Jvm() {
lifecycle = new AqualityTrackingLifecycle();
}

@Override
public void setEventPublisher(EventPublisher eventPublisher) {
if (lifecycle.isEnabled()) {
eventPublisher.registerHandlerFor(TestRunStarted.class, this::handleTestRunStartedEvent);
eventPublisher.registerHandlerFor(TestRunFinished.class, this::handleTestRunFinishedEvent);

eventPublisher.registerHandlerFor(TestCaseStarted.class, this::handleTestCaseStartedEvent);
eventPublisher.registerHandlerFor(TestCaseFinished.class, this::handleTestCaseFinishedEvent);

eventPublisher.registerHandlerFor(EmbedEvent.class, this::handleEmbedEvent);
}
}

private void handleTestRunStartedEvent(final TestRunStarted event) {
lifecycle.startTestRun();
}

private void handleTestRunFinishedEvent(final TestRunFinished event) {
lifecycle.finishTestRun();
}

private void handleTestCaseStartedEvent(final TestCaseStarted event) {
String testName = new TestCaseNameParser(event.getTestCase()).parse();
lifecycle.startTestExecution(testName);
}

private void handleTestCaseFinishedEvent(final TestCaseFinished event) {
TestCaseResultParser testCaseResultParser = new TestCaseResultParser(event.result);
TestCaseResultParser.TestCaseResult testCaseResult = testCaseResultParser.parse();
lifecycle.finishTestExecution(testCaseResult.getFinalResultId(), testCaseResult.getFailReason());
}

private void handleEmbedEvent(final EmbedEvent event) {
String fileName = format("%s_%s", UUID.randomUUID(), event.name);
lifecycle.addAttachment(fileName, event.data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package aquality.tracking.integrations.cucumber4jvm;

import aquality.tracking.integrations.core.AqualityUncheckedException;
import cucumber.api.TestCase;
import gherkin.AstBuilder;
import gherkin.Parser;
import gherkin.TokenMatcher;
import gherkin.ast.Feature;
import gherkin.ast.GherkinDocument;
import gherkin.ast.ScenarioOutline;
import gherkin.ast.TableRow;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static aquality.tracking.integrations.core.utilities.FileUtils.getFileSource;
import static java.lang.String.format;

class TestCaseNameParser {

private final TestCase testCase;

TestCaseNameParser(TestCase testCase) {
this.testCase = testCase;
}

public String parse() {
Feature currentFeature = getCurrentFeature();
String scenarioName = getScenarioName(currentFeature, testCase.getName());
return format("%s: %s", currentFeature.getName(), scenarioName);
}

private Feature getCurrentFeature() {
Parser<GherkinDocument> parser = new Parser<>(new AstBuilder());
TokenMatcher matcher = new TokenMatcher();
GherkinDocument gherkinDocument;
try {
String relativePathToFeatureFile = new URI(testCase.getUri()).getSchemeSpecificPart();
Path pathToFeatureFile = Paths.get(System.getProperty("user.dir"), relativePathToFeatureFile);

gherkinDocument = parser.parse(getFileSource(pathToFeatureFile), matcher);
} catch (URISyntaxException e) {
throw new AqualityUncheckedException(format("Failed to find feature file with URI: %s", testCase.getUri()), e);
}
return gherkinDocument.getFeature();
}

private String getScenarioName(final Feature feature, final String testCaseName) {
List<TableRow> examplesTableRows = feature.getChildren().stream()
.filter(child -> child.getName().equals(testCaseName))
.filter(child -> child instanceof ScenarioOutline)
.map(node -> ((ScenarioOutline) node).getExamples().get(0))
.flatMap(examples -> examples.getTableBody().stream())
.collect(Collectors.toList());

int tableRowIndex = IntStream.range(0, examplesTableRows.size())
.filter(i -> examplesTableRows.get(i).getLocation().getLine() == testCase.getLine())
.findFirst()
.orElse(-1);

return tableRowIndex == -1
? testCaseName
: format("%s: %d", testCaseName, tableRowIndex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package aquality.tracking.integrations.cucumber4jvm;

import aquality.tracking.integrations.core.FinalResultId;
import cucumber.api.Result;
import lombok.Data;
import org.apache.commons.lang3.exception.ExceptionUtils;

import static java.lang.String.format;

class TestCaseResultParser {

private final Result result;

TestCaseResultParser(Result result) {
this.result = result;
}

TestCaseResult parse() {
TestCaseResult testCaseResult = new TestCaseResult();
switch (result.getStatus()) {
case PASSED:
testCaseResult.setFinalResultId(FinalResultId.PASSED);
break;
case FAILED:
testCaseResult.setFinalResultId(FinalResultId.FAILED);
testCaseResult.setFailReason(formatErrorMessage(result.getError()));
break;
case PENDING:
testCaseResult.setFinalResultId(FinalResultId.PENDING);
testCaseResult.setFailReason(getShortErrorMessage(result.getError()));
break;
case SKIPPED:
testCaseResult.setFinalResultId(FinalResultId.PENDING);
testCaseResult.setFailReason("Test skipped");
break;
default:
testCaseResult.setFinalResultId(FinalResultId.NOT_EXECUTED);
}
return testCaseResult;
}

private String formatErrorMessage(final Throwable error) {
final String message = getShortErrorMessage(error);
final String stackTrace = ExceptionUtils.getStackTrace(error);
return format("Message:%n%s%n%nStack Trace:%n%s", message, stackTrace);
}

private String getShortErrorMessage(final Throwable error) {
return error.getMessage().split("\n")[0];
}

@Data
static class TestCaseResult {
private int finalResultId;
private String failReason;
}
}
6 changes: 3 additions & 3 deletions aquality-tracking-cucumber5-jvm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<modelVersion>4.0.0</modelVersion>

<artifactId>aquality-tracking-cucumber5-jvm</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
<packaging>jar</packaging>

<parent>
<artifactId>aquality-tracking-integrations</artifactId>
<groupId>com.github.aquality-automation</groupId>
<version>1.1.0</version>
<version>1.2.0</version>
</parent>

<name>Aquality Tracking Cucumber 5 JVM</name>
Expand All @@ -28,7 +28,7 @@
<dependency>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-tracking-integrations-core</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private void handleTestRunFinishedEvent(final TestRunFinished event) {
}

private void handleTestCaseStartedEvent(final TestCaseStarted event) {
String testName = new TestCaseNameParser(event.getTestCase()).getScenarioName();
String testName = new TestCaseNameParser(event.getTestCase()).parse();
lifecycle.startTestExecution(testName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,15 @@

class TestCaseNameParser {

private static final String SCENARIO_OUTLINE_KEYWORD = "Scenario Outline";
private static final String SCENARIO_TEMPLATE_KEYWORD = "Scenario Template";

private final TestCase testCase;

TestCaseNameParser(TestCase testCase) {
this.testCase = testCase;
}

public String getScenarioName() {
public String parse() {
Feature currentFeature = getCurrentFeature();
String scenarioName = testCase.getName();
String scenarioKeyword = testCase.getKeyword();
if (scenarioKeyword.equals(SCENARIO_OUTLINE_KEYWORD) || scenarioKeyword.equals(SCENARIO_TEMPLATE_KEYWORD)) {
scenarioName = getScenarioOutlineName(currentFeature, scenarioName);
}
String scenarioName = getScenarioName(currentFeature, testCase.getName());
return format("%s: %s", currentFeature.getName(), scenarioName);
}

Expand All @@ -44,11 +37,11 @@ private Feature getCurrentFeature() {
return gherkinDocument.getFeature();
}

private String getScenarioOutlineName(final Feature feature, final String scenarioName) {
private String getScenarioName(final Feature feature, final String testCaseName) {
List<TableRow> examplesTableRows = feature.getChildren().stream()
.filter(child -> child.getName().equals(scenarioName))
.map(node -> (ScenarioOutline) node)
.map(outline -> outline.getExamples().get(0))
.filter(child -> child.getName().equals(testCaseName))
.filter(child -> child instanceof ScenarioOutline)
.map(node -> ((ScenarioOutline) node).getExamples().get(0))
.flatMap(examples -> examples.getTableBody().stream())
.collect(Collectors.toList());

Expand All @@ -57,9 +50,8 @@ private String getScenarioOutlineName(final Feature feature, final String scenar
.findFirst()
.orElse(-1);

final String exampleLine = tableRowIndex == -1
? "EXAMPLE_LINE_NOT_FOUND"
: String.valueOf(tableRowIndex);
return format("%s: %s", scenarioName, exampleLine);
return tableRowIndex == -1
? testCaseName
: format("%s: %d", testCaseName, tableRowIndex);
}
}
4 changes: 2 additions & 2 deletions aquality-tracking-integrations-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<modelVersion>4.0.0</modelVersion>

<artifactId>aquality-tracking-integrations-core</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
<packaging>jar</packaging>

<parent>
<artifactId>aquality-tracking-integrations</artifactId>
<groupId>com.github.aquality-automation</groupId>
<version>1.1.0</version>
<version>1.2.0</version>
</parent>

<name>Aquality Tracking integrations core</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private List<Header> getDefaultHeaders() {
List<Header> headers = new ArrayList<>();
headers.add(getBasicAuthHeader());
headers.add(new BasicHeader(HttpHeaders.ACCEPT, APPLICATION_JSON.getMimeType()));
headers.add(new BasicHeader(HttpHeaders.CONTENT_TYPE, WILDCARD.getMimeType()));
headers.add(new BasicHeader(HttpHeaders.ACCEPT, WILDCARD.getMimeType()));
return headers;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
public class Test {
private Integer id;
private String name;
private String body;
@JsonProperty("project_id")
private Integer projectId;
private List<Suite> suites;
Expand Down
Loading

0 comments on commit 4f59f7b

Please sign in to comment.