diff --git a/libraries/pom.xml b/libraries/pom.xml
index 0643e8257b..021e081eb5 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -45,6 +45,20 @@
+
+ net.serenity-bdd.maven.plugins
+ serenity-maven-plugin
+ ${serenity.plugin.version}
+
+
+ serenity-reports
+ post-integration-test
+
+ aggregate
+
+
+
+
@@ -123,26 +137,6 @@
commons-io
${commons.io.version}
-
- org.eclipse.jetty
- jetty-server
- ${jetty.version}
-
-
- org.eclipse.jetty
- jetty-servlet
- ${jetty.version}
-
-
- org.apache.httpcomponents
- httpclient
- ${httpclient.version}
-
-
- commons-io
- commons-io
- ${commons.io.version}
-
org.apache.flink
flink-core
@@ -176,6 +170,36 @@
commons-math3
3.6.1
+
+ net.serenity-bdd
+ serenity-core
+ ${serenity.version}
+
+
+ net.serenity-bdd
+ serenity-junit
+ ${serenity.version}
+
+
+ net.serenity-bdd
+ serenity-jbehave
+ ${serenity.jbehave.version}
+
+
+ net.serenity-bdd
+ serenity-rest-assured
+ ${serenity.version}
+
+
+ net.serenity-bdd
+ serenity-jira-requirements-provider
+ ${serenity.jira.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
@@ -195,6 +219,11 @@
4.5.3
2.5
1.2.0
+ 2.8.5
+ 1.2.5-rc.11
+ 1.24.0
+ 1.1.3-rc.5
+ 1.2.5-rc.6
2.19.1
diff --git a/libraries/serenity.properties b/libraries/serenity.properties
new file mode 100644
index 0000000000..c77df9c0f7
--- /dev/null
+++ b/libraries/serenity.properties
@@ -0,0 +1,4 @@
+jira.url=
+jira.project=
+jira.username=
+jira.password=
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/serenity/github/GitHubUser.java b/libraries/src/main/java/com/baeldung/serenity/github/GitHubUser.java
new file mode 100644
index 0000000000..5b0998dba1
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/serenity/github/GitHubUser.java
@@ -0,0 +1,19 @@
+package com.baeldung.serenity.github;
+
+public class GitHubUser {
+
+ private String login;
+
+ public GitHubUser() {
+ super();
+ }
+
+ public String getLogin() {
+ return login;
+ }
+
+ public void setLogin(final String login) {
+ this.login = login;
+ }
+
+}
diff --git a/libraries/src/main/java/com/baeldung/serenity/membership/Commodity.java b/libraries/src/main/java/com/baeldung/serenity/membership/Commodity.java
new file mode 100644
index 0000000000..208b73d4af
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/serenity/membership/Commodity.java
@@ -0,0 +1,16 @@
+package com.baeldung.serenity.membership;
+
+/**
+ * @author aiet
+ */
+public enum Commodity {
+
+ MacBookPro(1499), GoProHero5(400);
+
+ public final int price;
+
+ Commodity(int price){
+ this.price = price;
+ }
+
+}
diff --git a/libraries/src/main/java/com/baeldung/serenity/membership/Member.java b/libraries/src/main/java/com/baeldung/serenity/membership/Member.java
new file mode 100644
index 0000000000..6e7c4db08e
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/serenity/membership/Member.java
@@ -0,0 +1,34 @@
+package com.baeldung.serenity.membership;
+
+import static com.baeldung.serenity.membership.MemberGrade.Bronze;
+import static com.baeldung.serenity.membership.MemberGrade.Gold;
+import static com.baeldung.serenity.membership.MemberGrade.Silver;
+
+/**
+ * @author aiet
+ */
+public class Member {
+
+ private int points;
+
+ private Member(int points) {
+ if (points < 0) throw new IllegalArgumentException("points must not be negative!");
+ this.points = points;
+
+ }
+
+ public static Member withInitialPoints(int initialPoints) {
+ return new Member(initialPoints);
+ }
+
+ public MemberGrade getGrade() {
+ if (points < 1000) return Bronze;
+ else if (points >= 1000 && points < 5000) return Silver;
+ else return Gold;
+ }
+
+ public void spend(int moneySpent) {
+ points += moneySpent / 10;
+ }
+
+}
diff --git a/libraries/src/main/java/com/baeldung/serenity/membership/MemberGrade.java b/libraries/src/main/java/com/baeldung/serenity/membership/MemberGrade.java
new file mode 100644
index 0000000000..7bb6f76495
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/serenity/membership/MemberGrade.java
@@ -0,0 +1,10 @@
+package com.baeldung.serenity.membership;
+
+/**
+ * @author aiet
+ */
+public enum MemberGrade {
+
+ Bronze, Silver, Gold;
+
+}
diff --git a/libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadTest.java b/libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadTest.java
new file mode 100644
index 0000000000..f8a2d6fa3c
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadTest.java
@@ -0,0 +1,10 @@
+package com.baeldung.serenity;
+
+import net.serenitybdd.jbehave.SerenityStory;
+
+/**
+ * @author aiet
+ */
+public class GithubUserProfilePayloadTest extends SerenityStory {
+
+}
diff --git a/libraries/src/test/java/com/baeldung/serenity/MemberStatusTest.java b/libraries/src/test/java/com/baeldung/serenity/MemberStatusTest.java
new file mode 100644
index 0000000000..5c90e90eb7
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/serenity/MemberStatusTest.java
@@ -0,0 +1,73 @@
+package com.baeldung.serenity;
+
+import com.baeldung.serenity.membership.MemberStatusSteps;
+import net.serenitybdd.junit.runners.SerenityRunner;
+import net.thucydides.core.annotations.Steps;
+import net.thucydides.core.annotations.Title;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static com.baeldung.serenity.membership.Commodity.MacBookPro;
+import static com.baeldung.serenity.membership.MemberGrade.Bronze;
+import static com.baeldung.serenity.membership.MemberGrade.Gold;
+import static com.baeldung.serenity.membership.MemberGrade.Silver;
+
+@RunWith(SerenityRunner.class)
+public class MemberStatusTest {
+
+ @Steps MemberStatusSteps memberSteps;
+
+ @Test
+ public void membersShouldStartWithBronzeStatus() {
+ memberSteps.aClientJoinsTheMemberProgram();
+ memberSteps.theMemberShouldHaveAStatusOf(Bronze);
+ }
+
+ @Test
+ @Title("Members earn Silver grade after 1000 points ($10,000)")
+ public void earnsSilverAfterSpends$10000() {
+ memberSteps.aClientJoinsTheMemberProgram();
+ memberSteps.theMemberSpends(10_000);
+ memberSteps.theMemberShouldHaveAStatusOf(Silver);
+ }
+
+ @Test
+ @Title("Members with 2,000 points should earn Gold grade when added 3,000 points ($30,000)")
+ public void memberWith2000PointsEarnsGoldAfterSpends$30000() {
+ memberSteps.aMemberHasPointsOf(2000);
+ memberSteps.theMemberSpends(30_000);
+ memberSteps.theMemberShouldHaveAStatusOf(Gold);
+ }
+
+ @Test
+ @Title("Members with 50,000 points can exchange a MacBook Pro")
+ public void memberWith50000PointsCanExchangeAMacbookpro(){
+ memberSteps.aMemberHasPointsOf(50_000);
+ memberSteps.aMemberExchangeA(MacBookPro);
+ memberSteps.memberShouldHavePointsLeft();
+ }
+
+ /**
+ * This test should fail, comment out @Ignore
to see how failed test can be reflected in Serenity report.
+ * Remember to add <testFailureIgnore>true</testFailureIgnore>
under maven-surefire-plugin configuration.
+ */
+ @Test
+ @Ignore
+ @Title("Members with 500 points should have a Gold status when added 4,000 points ($40,000)")
+ public void memberWith500PointsEarnsGoldAfterSpends$40000(){
+ memberSteps.aMemberHasPointsOf(500);
+ memberSteps.theMemberSpends(40_000);
+ memberSteps.theMemberShouldHaveAStatusOf(Gold);
+ }
+
+ @Test
+ @Ignore
+ @Title("Members with 100 points would have a Gold status when added 10,000 points ($100,000)")
+ public void memberWith100EarnsGoldAfterSpends$100000(){
+ memberSteps.aMemberHasPointsOf(100);
+ memberSteps.theMemberSpends(100_000);
+ memberSteps.theMemberShouldHaveAStatusOf(Gold);
+ }
+
+}
diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java b/libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java
new file mode 100644
index 0000000000..cc434d6d19
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java
@@ -0,0 +1,33 @@
+package com.baeldung.serenity.github;
+
+import net.thucydides.core.annotations.Step;
+import org.hamcrest.Matchers;
+
+import java.io.IOException;
+
+import static net.serenitybdd.rest.SerenityRest.rest;
+import static net.serenitybdd.rest.SerenityRest.then;
+
+/**
+ * @author aiet
+ */
+public class GithubRestAssuredUserAPISteps {
+
+ private String api;
+
+ @Step("Given the github REST API for user profile")
+ public void withUserProfileAPIEndpoint() {
+ api = "https://api.github.com/users/{username}";
+ }
+
+ @Step("When looking for {0} via the api")
+ public void getProfileOfUser(String username) throws IOException {
+ rest().get(api, username);
+ }
+
+ @Step("Then there should be a login field with value {0} in payload of user {0}")
+ public void profilePayloadShouldContainLoginValue(String username) {
+ then().body("login", Matchers.equalTo(username));
+ }
+
+}
diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java b/libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java
new file mode 100644
index 0000000000..6e7fbace49
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java
@@ -0,0 +1,54 @@
+package com.baeldung.serenity.github;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import net.thucydides.core.annotations.Step;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.hamcrest.Matchers;
+
+import java.io.IOException;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * @author aiet
+ */
+public class GithubRestUserAPISteps {
+
+ private String api;
+ private GitHubUser resource;
+
+ @Step("Given the github REST API for user profile")
+ public void withUserProfileAPIEndpoint() {
+ api = "https://api.github.com/users/%s";
+ }
+
+ @Step("When looking for {0} via the api")
+ public void getProfileOfUser(String username) throws IOException {
+ HttpResponse httpResponse = getGithubUserProfile(api, username);
+ resource = retrieveResourceFromResponse(httpResponse, GitHubUser.class);
+ }
+
+ @Step("Then there should be a login field with value {0} in payload of user {0}")
+ public void profilePayloadShouldContainLoginValue(String username) {
+ assertThat(username, Matchers.is(resource.getLogin()));
+ }
+
+ private static T retrieveResourceFromResponse(final HttpResponse response, final Class clazz) throws IOException {
+ final String jsonFromResponse = EntityUtils.toString(response.getEntity());
+ final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ return mapper.readValue(jsonFromResponse, clazz);
+ }
+
+ private static HttpResponse getGithubUserProfile(String api, String username) throws IOException {
+ HttpUriRequest request = new HttpGet(String.format(api, username));
+ return HttpClientBuilder
+ .create()
+ .build()
+ .execute(request);
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java b/libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java
new file mode 100644
index 0000000000..f3b374b66c
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java
@@ -0,0 +1,33 @@
+package com.baeldung.serenity.github;
+
+import net.thucydides.core.annotations.Steps;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+
+import java.io.IOException;
+
+public class GithubUserProfilePayloadStepDefinitions {
+
+// @Steps
+// GithubRestUserAPISteps userAPISteps;
+
+ @Steps
+ GithubRestAssuredUserAPISteps userAPISteps;
+
+ @Given("github user profile api")
+ public void givenGithubUserProfileApi() {
+ userAPISteps.withUserProfileAPIEndpoint();
+ }
+
+ @When("looking for $user via the api")
+ public void whenLookingForProfileOf(String user) throws IOException {
+ userAPISteps.getProfileOfUser(user);
+ }
+
+ @Then("github's response contains a 'login' payload same as $user")
+ public void thenGithubsResponseContainsAloginPayloadSameAs(String user) {
+ userAPISteps.profilePayloadShouldContainLoginValue(user);
+ }
+
+}
diff --git a/libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java b/libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java
new file mode 100644
index 0000000000..02b3f0130e
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java
@@ -0,0 +1,47 @@
+package com.baeldung.serenity.membership;
+
+import net.thucydides.core.annotations.Pending;
+import net.thucydides.core.annotations.Step;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author aiet
+ */
+public class MemberStatusSteps {
+
+ Member member;
+
+ @Step("Given a member has {0} points")
+ public void aMemberHasPointsOf(int points) {
+ member = Member.withInitialPoints(points);
+ }
+
+ @Step("Then the member grade should be {0}")
+ public void theMemberShouldHaveAStatusOf(MemberGrade grade) {
+ assertThat(member.getGrade(), equalTo(grade));
+ }
+
+ @Step("When the member spends ${0} ")
+ public void theMemberSpends(int moneySpent) {
+ member.spend(moneySpent);
+ }
+
+ @Step("Given client joins membership program")
+ public void aClientJoinsTheMemberProgram() {
+ member = Member.withInitialPoints(0);
+ }
+
+ @Pending
+ @Step("When the member exchange {}")
+ public void aMemberExchangeA(Commodity commodity){
+ //TODO
+ }
+
+ @Pending
+ @Step("Then the member should have points left")
+ public void memberShouldHavePointsLeft() {
+
+ }
+}
diff --git a/libraries/src/test/resources/stories/github_rest/user_profile/github_user_profile_payload_test.story b/libraries/src/test/resources/stories/github_rest/user_profile/github_user_profile_payload_test.story
new file mode 100644
index 0000000000..841bf901b5
--- /dev/null
+++ b/libraries/src/test/resources/stories/github_rest/user_profile/github_user_profile_payload_test.story
@@ -0,0 +1,13 @@
+
+Meta:
+
+Narrative:
+As a user
+I want to look up a valid user's profile on github
+So that I can know the login payload should be the same as username
+
+Scenario: Github user's profile should have a login payload same as username
+
+Given github user profile api
+When looking for eugenp via the api
+Then github's response contains a 'login' payload same as eugenp