Skip to content

Commit

Permalink
Added a check to ensure that tags are correctly written
Browse files Browse the repository at this point in the history
  • Loading branch information
wakaleo committed Jun 6, 2024
1 parent 82248ce commit ad4929d
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import io.cucumber.core.backend.ObjectFactory;
import io.cucumber.core.exception.CucumberException;
import io.cucumber.core.plugin.ConfigureDriverFromTags;
import net.serenitybdd.core.Serenity;
import net.serenitybdd.core.annotations.events.BeforeScenario;
import net.serenitybdd.core.lifecycle.LifecycleRegister;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,45 @@ public void setupPlugin() {
plugin = new SerenityGherkinCheckerMojo();
plugin.project = project;
plugin.session = Mockito.mock(MavenSession.class);
plugin.featureFilesDirectory = "src/test/resources/ecommerce_features";
MavenProject project=Mockito.mock(MavenProject.class);
Mockito.when(project.getBasedir()).thenReturn(new File("."));
Mockito.when(plugin.session.getCurrentProject()).thenReturn(project);
}

@Test(expected = MojoFailureException.class)
public void should_fail_if_there_are_gherkin_errors() throws Exception {
plugin.featureFilesDirectory = "src/test/resources/ecommerce_features";
plugin.execute();
}

@Test(expected = MojoFailureException.class)
public void should_fail_if_there_are_incorrect_tags_in_a_scenario() throws Exception {
plugin.featureFilesDirectory = "src/test/resources/bad_tags_example/bad_tag_in_scenario";
plugin.execute();
}

@Test(expected = MojoFailureException.class)
public void should_fail_if_there_are_incorrect_tags_in_a_nested_scenario() throws Exception {
plugin.featureFilesDirectory = "src/test/resources/bad_tags_example/bad_tag_in_nested_scenario";
plugin.execute();
}

@Test(expected = MojoFailureException.class)
public void should_fail_if_there_are_incorrect_tags_in_a_rule() throws Exception {
plugin.featureFilesDirectory = "src/test/resources/bad_tags_example/bad_tag_in_rule";
plugin.execute();
}

@Test(expected = MojoFailureException.class)
public void should_fail_if_there_are_incorrect_tags_in_exmaples() throws Exception {
plugin.featureFilesDirectory = "src/test/resources/bad_tags_example/bad_tag_in_example";
plugin.execute();
}

@Test(expected = MojoFailureException.class)
public void should_fail_if_there_are_incorrect_tags_in_a_feature() throws Exception {
plugin.featureFilesDirectory = "src/test/resources/bad_tags_example/bad_tag_in_feature";
plugin.execute();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@singlebrowser
@authentication
Feature: Login's all good

@test
@smoke
Scenario: Colin logs in with Colin's valid credentials
Given Colin is on the login page
When Colin logs in with valid credentials
Then he should be presented the product catalog

@test
Scenario Outline: Login's with invalid credentials for <username>
Given Colin is on the login page
When Colin attempts to login with the following credentials:
| username | password |
| <username> | <password> |
Then he should be presented with the error message <message>
@issue:
Examples:
| username | password | message |
| standard_user | wrong_password | Username and password do not match any user in this service |
| unknown_user | secret_sauce | Username and password do not match any user in this service |
| unknown_user | wrong_password | Username and password do not match any user in this service |
| locked_out_user | secret_sauce | Sorry, this user has been locked out |

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@singlebrowser
@authentication
@issue:
Feature: Login's all good

Rule: Customers needs to provide valid credentials to access the site

@test
@smoke
Example: Colin logs in with Colin's valid credentials
Given Colin is on the login page
When Colin logs in with valid credentials
Then he should be presented the product catalog

@test
Scenario Outline: Login's with invalid credentials for <username>
Given Colin is on the login page
When Colin attempts to login with the following credentials:
| username | password |
| <username> | <password> |
Then he should be presented with the error message <message>
Examples:
| username | password | message |
| standard_user | wrong_password | Username and password do not match any user in this service |
| unknown_user | secret_sauce | Username and password do not match any user in this service |
| unknown_user | wrong_password | Username and password do not match any user in this service |
| locked_out_user | secret_sauce | Sorry, this user has been locked out |

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@singlebrowser
@authentication
@issue:
Feature: Login's all good

Rule: Customers needs to provide valid credentials to access the site

@test
@smoke
Example: Colin logs in with Colin's valid credentials
Given Colin is on the login page
When Colin logs in with valid credentials
Then he should be presented the product catalog

@test
Scenario Outline: Login's with invalid credentials for <username>
Given Colin is on the login page
When Colin attempts to login with the following credentials:
| username | password |
| <username> | <password> |
Then he should be presented with the error message <message>
Examples:
| username | password | message |
| standard_user | wrong_password | Username and password do not match any user in this service |
| unknown_user | secret_sauce | Username and password do not match any user in this service |
| unknown_user | wrong_password | Username and password do not match any user in this service |
| locked_out_user | secret_sauce | Sorry, this user has been locked out |

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@singlebrowser
@authentication
Feature: Login's all good

@issue:
Rule: Customers needs to provide valid credentials to access the site

@test
@smoke
Example: Colin logs in with Colin's valid credentials
Given Colin is on the login page
When Colin logs in with valid credentials
Then he should be presented the product catalog

@test
Scenario Outline: Login's with invalid credentials for <username>
Given Colin is on the login page
When Colin attempts to login with the following credentials:
| username | password |
| <username> | <password> |
Then he should be presented with the error message <message>
Examples:
| username | password | message |
| standard_user | wrong_password | Username and password do not match any user in this service |
| unknown_user | secret_sauce | Username and password do not match any user in this service |
| unknown_user | wrong_password | Username and password do not match any user in this service |
| locked_out_user | secret_sauce | Sorry, this user has been locked out |

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@singlebrowser
@authentication
Feature: Login's all good

@test
@smoke
@issue:
Scenario: Colin logs in with Colin's valid credentials
Given Colin is on the login page
When Colin logs in with valid credentials
Then he should be presented the product catalog

@test
Scenario Outline: Login's with invalid credentials for <username>
Given Colin is on the login page
When Colin attempts to login with the following credentials:
| username | password |
| <username> | <password> |
Then he should be presented with the error message <message>
Examples:
| username | password | message |
| standard_user | wrong_password | Username and password do not match any user in this service |
| unknown_user | secret_sauce | Username and password do not match any user in this service |
| unknown_user | wrong_password | Username and password do not match any user in this service |
| locked_out_user | secret_sauce | Sorry, this user has been locked out |

Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ private String findCardNumberInTags(List<Tag> tags) {
} else if (tag.getName().toLowerCase().startsWith("@issues:")) {
String issueNumberList = tag.getName().replaceAll("@issues:", "");
List<String> issueNumberTags = Splitter.on(",").trimResults().omitEmptyStrings().splitToList(issueNumberList);
return issueNumberTags.get(0);
return issueNumberTags.stream().findFirst().orElse("");
}
}
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package net.thucydides.model.requirements.model.cucumber;

import io.cucumber.messages.types.Feature;
import io.cucumber.messages.types.Rule;
import io.cucumber.messages.types.Scenario;
import io.cucumber.messages.types.Tag;

import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -29,10 +34,9 @@ public void check(Stream<File> files, boolean allowDuplicateFeatureNames) {
Optional<AnnotatedFeature> loadedFeature = cucumberParser.loadFeature(featureFile);
loadedFeature.ifPresent(
annotatedFeature -> {
recordFeaturePath(pathNamesToFeatureFiles,
featureFile,
annotatedFeature);
recordFeaturePath(pathNamesToFeatureFiles, featureFile, annotatedFeature);
featureFileNames.add(annotatedFeature.getFeature().getName());
checkTagsIn(annotatedFeature.getFeature());
}
);
return Optional.empty();
Expand Down Expand Up @@ -61,6 +65,54 @@ public void check(Stream<File> files, boolean allowDuplicateFeatureNames) {
}
}


private void checkTagsIn(Feature feature) {
checkTags(feature.getTags());
feature.getChildren().forEach(
child -> {
if (child.getScenario().isPresent()) {
checkTagsInScenario(child.getScenario().get());
} else if (child.getRule().isPresent()) {
checkTagsInRule(child.getRule().get());
}
}
);
}

private void checkTagsInScenario(Scenario scenario) {
checkTags(scenario.getTags());
if (!scenario.getExamples().isEmpty()) {
List<Tag> exampleTags = scenario.getExamples()
.stream()
.flatMap(examples -> examples.getTags().stream())
.collect(Collectors.toList());
checkTags(exampleTags);
}
}

private void checkTagsInRule(Rule rule) {
checkTags(rule.getTags());
rule.getChildren().forEach(
child -> {
if (child.getScenario().isPresent()) {
checkTagsInScenario(child.getScenario().get());
}
}
);
}

private void checkTags(List<Tag> tags) {
for(Tag tag : tags) {
if (tag.getName().trim().endsWith(":")) {
throw new InvalidFeatureFileException("Invalid tag format at " + tag.getLocation() + " - tags in the format <name>:<value> (e.g. '@color:red') must have a value after the colon");
}
if (tag.getName().trim().endsWith("=")) {
throw new InvalidFeatureFileException("Invalid tag format at " + tag.getLocation() + " - tags in the format <name>=<value> (e.g. '@color=red') must have a value after the equals sign");
}
}
}


private Collection<String> checkForDuplicateFeatureNames(List<String> featureFileNames) {
// Return the list of duplicate feature names in featureFileNames
return featureFileNames.stream()
Expand All @@ -77,7 +129,7 @@ private String duplicateFeaturePathsError(String key, List<File> value) {
.map(file -> " - " + file.getPath())
.collect(Collectors.joining(System.lineSeparator()));

return String.format("* " + DUPLICATE_FEATURE_NAME,key, featureFilesWithDuplicates);
return String.format("* " + DUPLICATE_FEATURE_NAME, key, featureFilesWithDuplicates);
}

private static void recordFeaturePath(ConcurrentHashMap<String, List<File>> pathNamesToFeatureFiles,
Expand Down

0 comments on commit ad4929d

Please sign in to comment.