├── .github
└── workflows
│ └── maven.yml
├── .gitignore
├── README.md
├── config.properties
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── api
│ │ ├── model
│ │ ├── BookingDTO.java
│ │ ├── BookingDates.java
│ │ ├── BookingDetailsDTO.java
│ │ └── BookingID.java
│ │ ├── stepdefinition
│ │ ├── CreateBookingStepdefinition.java
│ │ ├── DeleteBookingStepdefinition.java
│ │ ├── Hooks.java
│ │ ├── UpdateBookingStepdefinition.java
│ │ └── ViewBookingDetailsStepdefinition.java
│ │ └── utils
│ │ ├── ExcelUtils.java
│ │ ├── JsonReader.java
│ │ ├── MyTestListener.java
│ │ ├── PropertiesFile.java
│ │ ├── ResponseHandler.java
│ │ ├── RestAssuredRequestFilter.java
│ │ └── TestContext.java
└── resources
│ ├── extent-config.xml
│ └── log4j.properties
└── test
├── java
└── com
│ └── api
│ └── test
│ └── TestRunner.java
└── resources
├── cucumber.properties
├── data
├── bookingBody.json
└── testData.xlsx
├── extent.properties
├── features
├── CreateBooking.feature
├── DeleteBooking.feature
├── UpdateBooking.feature
└── ViewBookingDetails.feature
└── schemas
├── bookSchema.json
├── bookingDetailsSchema.json
├── createBookingSchema.json
└── userSchema.json
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: API Cucumber Workflow
5 |
6 | on:
7 | push:
8 | branches: [ "master" ]
9 |
10 | jobs:
11 | build:
12 |
13 | runs-on: windows-latest
14 |
15 | steps:
16 | - uses: actions/checkout@v3
17 | - name: Set up JDK 11
18 | uses: actions/setup-java@v3
19 | with:
20 | java-version: '11'
21 | distribution: 'temurin'
22 | cache: maven
23 | - name: Test execution
24 | run: mvn clean test
25 | - name: Upload execution report
26 | if: always()
27 | uses: actions/upload-artifact@v3
28 | with:
29 | name: report
30 | path: target/report
31 | - name: Upload execution logs
32 | if: always()
33 | uses: actions/upload-artifact@v3
34 | with:
35 | name: logs
36 | path: target/logs
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | /test-output/
26 | /target/
27 | /.classpath
28 | /.project
29 | /.settings
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # API-Cucumber
2 |
3 | ## **Overview:**
4 | API is the acronym for Application Programming Interface, which is a software intermediary that allows two applications to talk to each other. This API framework is developed using REST Assured and Cucumber. REST Assured is a Java library that provides a domain-specific language (DSL) for writing powerful, maintainable tests for RESTful APIs. Cucumber is an open source library, which supports behavior driven development. To be more precise, Cucumber can be defined as a testing framework, driven by plain English text. It serves as documentation, automated tests, and a development aid – all in one.
5 |
6 | For Demo purpose all the test cases are done on [Restful-booker](https://restful-booker.herokuapp.com/apidoc/index.html).
7 |
8 | ### **Some of the key features of this framework:**
9 |
10 | 1. It generates Extent report with all the step details. Report will be generated both HTML & PDF file format.
11 | 2. Generates execution logs, with detailed request and response details.
12 | 3. Feature file has examples of reading request details from json and excel file.
13 | 4. This also has an example to validate response body using json schema and java pojo classes.
14 | 5. Test execution can be triggered form command line.
15 | 6. Easy integration to CI/CD pipeline.
16 |
17 | ## **Required Setup :**
18 |
19 | - [Java](https://www.guru99.com/install-java.html) should be installed and configured.
20 | - [Maven](https://mkyong.com/maven/how-to-install-maven-in-windows/) should be installed and configured.
21 | - Download the files from Git repository either as zip file OR using [Git](https://phoenixnap.com/kb/how-to-install-git-windows).
22 |
23 | ## **Running Test:**
24 |
25 | Open the command prompt and navigate to the folder in which pom.xml file is present.
26 | Run the below Maven command.
27 |
28 | mvn clean test
29 |
30 |
31 | Once the execution completes report & log will be generated in below folder.
32 |
33 | **Report:** *target/report*
34 | **Log:** *target/logs*
--------------------------------------------------------------------------------
/config.properties:
--------------------------------------------------------------------------------
1 | username = vinay
2 | password = 1111
3 | baseURL = https://restful-booker.herokuapp.com
4 | test.data.path = src/test/resources/data/
5 | excel.name = testData.xlsx
6 | sheet.name = testData
7 | content.type = application/json
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | Cucumber
6 | APITesting
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | APITesting
11 | http://maven.apache.org
12 |
13 |
14 | 1.8
15 | 1.8
16 | UTF-8
17 | 6.9.1
18 | 5.2.2
19 | 2.0.0
20 |
21 |
22 |
23 |
24 |
25 | io.cucumber
26 | cucumber-java
27 | ${cucumber.version}
28 |
29 |
30 | io.cucumber
31 | cucumber-core
32 | ${cucumber.version}
33 |
34 |
35 |
36 | io.cucumber
37 | cucumber-junit
38 | ${cucumber.version}
39 |
40 |
41 |
42 | io.cucumber
43 | cucumber-picocontainer
44 | ${cucumber.version}
45 |
46 |
47 |
48 | io.cucumber
49 | cucumber-jvm-deps
50 | 1.0.6
51 |
52 |
53 |
54 | io.cucumber
55 | gherkin
56 | 5.0.0
57 |
58 |
59 |
60 | io.rest-assured
61 | rest-assured
62 | 3.3.0
63 |
64 |
65 |
66 | io.rest-assured
67 | json-schema-validator
68 | 3.3.0
69 |
70 |
71 |
72 | com.googlecode.json-simple
73 | json-simple
74 | 1.1.1
75 |
76 |
77 |
78 | org.apache.poi
79 | poi
80 | ${poi.version}
81 |
82 |
83 |
84 | org.apache.poi
85 | poi-ooxml
86 | ${poi.version}
87 |
88 |
89 |
90 | org.json
91 | json
92 | 20230227
93 |
94 |
95 |
96 | com.google.guava
97 | guava
98 | 32.0.0-jre
99 |
100 |
101 |
102 | com.fasterxml.jackson.core
103 | jackson-databind
104 | 2.13.4.2
105 |
106 |
107 |
108 | com.github.dzieciou.testing
109 | curl-logger
110 | 2.0.1
111 |
112 |
113 | org.slf4j
114 | slf4j-simple
115 | ${logger.version}
116 |
117 |
118 | org.slf4j
119 | slf4j-api
120 | ${logger.version}
121 |
122 |
123 | org.slf4j
124 | slf4j-reload4j
125 | ${logger.version}
126 |
127 |
128 |
129 | tech.grasshopper
130 | extentreports-cucumber6-adapter
131 | 2.13.0
132 |
133 |
134 |
135 |
136 |
137 | org.apache.maven.plugins
138 | maven-surefire-plugin
139 | 3.0.0-M3
140 |
141 |
142 | test
143 |
144 |
145 | com.api.test.TestRunner.java
146 |
147 | true
148 | true
149 |
150 |
151 |
152 |
153 |
154 | org.apache.maven.plugins
155 | maven-compiler-plugin
156 | 3.7.0
157 |
158 | 1.8
159 | 1.8
160 |
161 |
162 |
163 |
164 |
--------------------------------------------------------------------------------
/src/main/java/com/api/model/BookingDTO.java:
--------------------------------------------------------------------------------
1 | package com.api.model;
2 |
3 | public class BookingDTO
4 | {
5 | private BookingDetailsDTO booking;
6 |
7 | private String bookingid;
8 |
9 | public BookingDetailsDTO getBooking ()
10 | {
11 | return booking;
12 | }
13 |
14 | public void setBooking (BookingDetailsDTO booking)
15 | {
16 | this.booking = booking;
17 | }
18 |
19 | public String getBookingid ()
20 | {
21 | return bookingid;
22 | }
23 |
24 | public void setBookingid (String bookingid)
25 | {
26 | this.bookingid = bookingid;
27 | }
28 |
29 | @Override
30 | public String toString()
31 | {
32 | return "ClassPojo [booking = "+booking+", bookingid = "+bookingid+"]";
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/java/com/api/model/BookingDates.java:
--------------------------------------------------------------------------------
1 | package com.api.model;
2 |
3 | public class BookingDates {
4 | private String checkin;
5 |
6 | private String checkout;
7 |
8 | public String getCheckin ()
9 | {
10 | return checkin;
11 | }
12 |
13 | public void setCheckin (String checkin)
14 | {
15 | this.checkin = checkin;
16 | }
17 |
18 | public String getCheckout ()
19 | {
20 | return checkout;
21 | }
22 |
23 | public void setCheckout (String checkout)
24 | {
25 | this.checkout = checkout;
26 | }
27 |
28 | @Override
29 | public String toString()
30 | {
31 | return "ClassPojo [checkin = "+checkin+", checkout = "+checkout+"]";
32 | }
33 | }
--------------------------------------------------------------------------------
/src/main/java/com/api/model/BookingDetailsDTO.java:
--------------------------------------------------------------------------------
1 | package com.api.model;
2 |
3 | public class BookingDetailsDTO
4 | {
5 | private String firstname;
6 |
7 | private String additionalneeds;
8 |
9 | private BookingDates bookingdates;
10 |
11 | private String totalprice;
12 |
13 | private String depositpaid;
14 |
15 | private String lastname;
16 |
17 | public String getFirstname ()
18 | {
19 | return firstname;
20 | }
21 |
22 | public void setFirstname (String firstname)
23 | {
24 | this.firstname = firstname;
25 | }
26 |
27 | public String getAdditionalneeds ()
28 | {
29 | return additionalneeds;
30 | }
31 |
32 | public void setAdditionalneeds (String additionalneeds)
33 | {
34 | this.additionalneeds = additionalneeds;
35 | }
36 |
37 | public BookingDates getBookingdates ()
38 | {
39 | return bookingdates;
40 | }
41 |
42 | public void setBookingdates (BookingDates bookingdates)
43 | {
44 | this.bookingdates = bookingdates;
45 | }
46 |
47 | public String getTotalprice ()
48 | {
49 | return totalprice;
50 | }
51 |
52 | public void setTotalprice (String totalprice)
53 | {
54 | this.totalprice = totalprice;
55 | }
56 |
57 | public String getDepositpaid ()
58 | {
59 | return depositpaid;
60 | }
61 |
62 | public void setDepositpaid (String depositpaid)
63 | {
64 | this.depositpaid = depositpaid;
65 | }
66 |
67 | public String getLastname ()
68 | {
69 | return lastname;
70 | }
71 |
72 | public void setLastname (String lastname)
73 | {
74 | this.lastname = lastname;
75 | }
76 |
77 | @Override
78 | public String toString()
79 | {
80 | return "ClassPojo [firstname = "+firstname+", additionalneeds = "+additionalneeds+", bookingdates = "+bookingdates+", totalprice = "+totalprice+", depositpaid = "+depositpaid+", lastname = "+lastname+"]";
81 | }
82 | }
--------------------------------------------------------------------------------
/src/main/java/com/api/model/BookingID.java:
--------------------------------------------------------------------------------
1 | package com.api.model;
2 |
3 | public class BookingID {
4 | private String bookingid;
5 |
6 | public String getBookingid ()
7 | {
8 | return bookingid;
9 | }
10 |
11 | public void setBookingid (String bookingid)
12 | {
13 | this.bookingid = bookingid;
14 | }
15 |
16 | @Override
17 | public String toString()
18 | {
19 | return "ClassPojo [bookingid = "+bookingid+"]";
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/api/stepdefinition/CreateBookingStepdefinition.java:
--------------------------------------------------------------------------------
1 | package com.api.stepdefinition;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import java.util.Map;
6 |
7 | import org.apache.log4j.LogManager;
8 | import org.apache.log4j.Logger;
9 | import org.json.JSONObject;
10 |
11 | import com.api.model.BookingDTO;
12 | import com.api.utils.ExcelUtils;
13 | import com.api.utils.JsonReader;
14 | import com.api.utils.ResponseHandler;
15 | import com.api.utils.TestContext;
16 |
17 | import io.cucumber.datatable.DataTable;
18 | import io.cucumber.java.en.Then;
19 | import io.cucumber.java.en.When;
20 | import io.restassured.module.jsv.JsonSchemaValidator;
21 |
22 | public class CreateBookingStepdefinition {
23 | private TestContext context;
24 | private static final Logger LOG = LogManager.getLogger(CreateBookingStepdefinition.class);
25 |
26 | public CreateBookingStepdefinition(TestContext context) {
27 | this.context = context;
28 | }
29 |
30 | @When("user creates a booking")
31 | public void userCreatesABooking(DataTable dataTable) {
32 | Map bookingData = dataTable.asMaps().get(0);
33 | JSONObject bookingBody = new JSONObject();
34 | bookingBody.put("firstname", bookingData.get("firstname"));
35 | bookingBody.put("lastname", bookingData.get("lastname"));
36 | bookingBody.put("totalprice", Integer.valueOf(bookingData.get("totalprice")));
37 | bookingBody.put("depositpaid", Boolean.valueOf(bookingData.get("depositpaid")));
38 | JSONObject bookingDates = new JSONObject();
39 | bookingDates.put("checkin", (bookingData.get("checkin")));
40 | bookingDates.put("checkout", (bookingData.get("checkout")));
41 | bookingBody.put("bookingdates", bookingDates);
42 | bookingBody.put("additionalneeds", bookingData.get("additionalneeds"));
43 |
44 | context.response = context.requestSetup().body(bookingBody.toString())
45 | .when().post(context.session.get("endpoint").toString());
46 |
47 | BookingDTO bookingDTO = ResponseHandler.deserializedResponse(context.response, BookingDTO.class);
48 | assertNotNull("Booking not created", bookingDTO);
49 | LOG.info("Newly created booking ID: "+bookingDTO.getBookingid());
50 | context.session.put("bookingID", bookingDTO.getBookingid());
51 | validateBookingData(new JSONObject(bookingData), bookingDTO);
52 | }
53 |
54 | private void validateBookingData(JSONObject bookingData, BookingDTO bookingDTO) {
55 | LOG.info(bookingData);
56 | assertNotNull("Booking ID missing", bookingDTO.getBookingid());
57 | assertEquals("First Name did not match", bookingData.get("firstname"), bookingDTO.getBooking().getFirstname());
58 | assertEquals("Last Name did not match", bookingData.get("lastname"), bookingDTO.getBooking().getLastname());
59 | assertEquals("Total Price did not match", bookingData.get("totalprice"), bookingDTO.getBooking().getTotalprice());
60 | assertEquals("Deposit Paid did not match", bookingData.get("depositpaid"), bookingDTO.getBooking().getDepositpaid());
61 | assertEquals("Additional Needs did not match", bookingData.get("additionalneeds"), bookingDTO.getBooking().getAdditionalneeds());
62 | assertEquals("Check in Date did not match", bookingData.get("checkin"), bookingDTO.getBooking().getBookingdates().getCheckin());
63 | assertEquals("Check out Date did not match", bookingData.get("checkout"), bookingDTO.getBooking().getBookingdates().getCheckout());
64 | }
65 |
66 | @When("user creates a booking using data {string} from Excel")
67 | public void userCreatesABookingUsingDataFromExcel(String dataKey) throws Exception {
68 | Map excelDataMap = ExcelUtils.getData(dataKey);
69 | context.response = context.requestSetup().body(excelDataMap.get("requestBody"))
70 | .when().post(context.session.get("endpoint").toString());
71 |
72 | BookingDTO bookingDTO = ResponseHandler.deserializedResponse(context.response, BookingDTO.class);
73 | assertNotNull("Booking not created", bookingDTO);
74 | LOG.info("Newly created booking ID: "+bookingDTO.getBookingid());
75 | context.session.put("bookingID", bookingDTO.getBookingid());
76 | validateBookingData(new JSONObject(excelDataMap.get("responseBody")), bookingDTO);
77 | context.session.put("excelDataMap", excelDataMap);
78 | }
79 |
80 | @Then("user validates the response with JSON schema from Excel")
81 | public void userValidatesTheResponseWithJSONSchemaFromExcel() {
82 | context.response.then().assertThat().body(JsonSchemaValidator.matchesJsonSchema(((Map) context.session.get("excelDataMap")).get("responseSchema")));
83 | LOG.info("Successfully Validated schema from Excel");
84 | }
85 |
86 | @When("user creates a booking using data {string} from JSON file {string}")
87 | public void userCreatesABookingUsingDataFromJSONFile(String dataKey, String JSONFile) {
88 | context.response = context.requestSetup().body(JsonReader.getRequestBody(JSONFile,dataKey))
89 | .when().post(context.session.get("endpoint").toString());
90 |
91 | BookingDTO bookingDTO = ResponseHandler.deserializedResponse(context.response, BookingDTO.class);
92 | assertNotNull("Booking not created", bookingDTO);
93 | LOG.info("Newly created booking ID: "+bookingDTO.getBookingid());
94 | context.session.put("bookingID", bookingDTO.getBookingid());
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/com/api/stepdefinition/DeleteBookingStepdefinition.java:
--------------------------------------------------------------------------------
1 | package com.api.stepdefinition;
2 |
3 | import com.api.utils.TestContext;
4 |
5 | import io.cucumber.java.en.When;
6 |
7 | public class DeleteBookingStepdefinition {
8 | private TestContext context;
9 |
10 | public DeleteBookingStepdefinition(TestContext context) {
11 | this.context = context;
12 | }
13 |
14 | @When("user makes a request to delete booking with basic auth {string} & {string}")
15 | public void userMakesARequestToDeleteBookingWithBasicAuth(String username, String password) {
16 | context.response = context.requestSetup()
17 | .auth().preemptive().basic(username, password)
18 | .pathParam("bookingID", context.session.get("bookingID"))
19 | .when().delete(context.session.get("endpoint")+"/{bookingID}");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/api/stepdefinition/Hooks.java:
--------------------------------------------------------------------------------
1 | package com.api.stepdefinition;
2 |
3 | import org.apache.log4j.LogManager;
4 | import org.apache.log4j.Logger;
5 |
6 | import io.cucumber.java.Before;
7 | import io.cucumber.java.Scenario;
8 |
9 | public class Hooks {
10 |
11 | private static final Logger LOG = LogManager.getLogger(Hooks.class);
12 |
13 | @Before
14 | public void testStart(Scenario scenario) {
15 | LOG.info("*****************************************************************************************");
16 | LOG.info(" Scenario: "+scenario.getName());
17 | LOG.info("*****************************************************************************************");
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/api/stepdefinition/UpdateBookingStepdefinition.java:
--------------------------------------------------------------------------------
1 | package com.api.stepdefinition;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import java.util.Map;
6 |
7 | import org.apache.log4j.LogManager;
8 | import org.apache.log4j.Logger;
9 | import org.json.JSONObject;
10 |
11 | import com.api.model.BookingDetailsDTO;
12 | import com.api.utils.ExcelUtils;
13 | import com.api.utils.JsonReader;
14 | import com.api.utils.ResponseHandler;
15 | import com.api.utils.TestContext;
16 |
17 | import io.cucumber.java.en.When;
18 | import io.cucumber.datatable.DataTable;
19 |
20 | public class UpdateBookingStepdefinition {
21 | private TestContext context;
22 | private static final Logger LOG = LogManager.getLogger(UpdateBookingStepdefinition.class);
23 |
24 | public UpdateBookingStepdefinition(TestContext context) {
25 | this.context = context;
26 | }
27 |
28 | @When("user creates a auth token with credential {string} & {string}")
29 | public void userCreatesAAuthTokenWithCredential(String username, String password) {
30 | JSONObject credentials = new JSONObject();
31 | credentials.put("username", username);
32 | credentials.put("password", password);
33 | context.response = context.requestSetup().body(credentials.toString())
34 | .when().post(context.session.get("endpoint").toString());
35 | String token = context.response.path("token");
36 | LOG.info("Auth Token: "+token);
37 | context.session.put("token", "token="+token);
38 | }
39 |
40 | @When("user updates the details of a booking")
41 | public void userUpdatesABooking(DataTable dataTable) {
42 | Map bookingData = dataTable.asMaps().get(0);
43 | JSONObject bookingBody = new JSONObject();
44 | bookingBody.put("firstname", bookingData.get("firstname"));
45 | bookingBody.put("lastname", bookingData.get("lastname"));
46 | bookingBody.put("totalprice", Integer.valueOf(bookingData.get("totalprice")));
47 | bookingBody.put("depositpaid", Boolean.valueOf(bookingData.get("depositpaid")));
48 | JSONObject bookingDates = new JSONObject();
49 | bookingDates.put("checkin", (bookingData.get("checkin")));
50 | bookingDates.put("checkout", (bookingData.get("checkout")));
51 | bookingBody.put("bookingdates", bookingDates);
52 | bookingBody.put("additionalneeds", bookingData.get("additionalneeds"));
53 |
54 | context.response = context.requestSetup()
55 | .header("Cookie", context.session.get("token").toString())
56 | .pathParam("bookingID", context.session.get("bookingID"))
57 | .body(bookingBody.toString())
58 | .when().put(context.session.get("endpoint")+"/{bookingID}");
59 |
60 | BookingDetailsDTO bookingDetailsDTO = ResponseHandler.deserializedResponse(context.response, BookingDetailsDTO.class);
61 | assertNotNull("Booking not created", bookingDetailsDTO);
62 | }
63 |
64 | @When("user updates the booking details using data {string} from Excel")
65 | public void userUpdatesTheBookingDetailsUsingDataFromExcel(String dataKey) throws Exception {
66 | Map excelDataMap = ExcelUtils.getData(dataKey);
67 | context.response = context.requestSetup()
68 | .header("Cookie", context.session.get("token").toString())
69 | .pathParam("bookingID", context.session.get("bookingID"))
70 | .body(excelDataMap.get("requestBody"))
71 | .when().put(context.session.get("endpoint")+"/{bookingID}");
72 |
73 | BookingDetailsDTO bookingDetailsDTO = ResponseHandler.deserializedResponse(context.response, BookingDetailsDTO.class);
74 | assertNotNull("Booking not created", bookingDetailsDTO);
75 | context.session.put("excelDataMap", excelDataMap);
76 | }
77 |
78 | @When("user updates the booking details using data {string} from JSON file {string}")
79 | public void userUpdatesTheBookingDetailsUsingDataFromJSONFile(String dataKey, String JSONFile) {
80 | context.response = context.requestSetup()
81 | .header("Cookie", context.session.get("token").toString())
82 | .pathParam("bookingID", context.session.get("bookingID"))
83 | .body(JsonReader.getRequestBody(JSONFile,dataKey))
84 | .when().put(context.session.get("endpoint")+"/{bookingID}");
85 |
86 | BookingDetailsDTO bookingDetailsDTO = ResponseHandler.deserializedResponse(context.response, BookingDetailsDTO.class);
87 | assertNotNull("Booking not created", bookingDetailsDTO);
88 | }
89 |
90 | @When("user makes a request to update first name {string} & Last name {string}")
91 | public void userMakesARequestToUpdateFirstNameLastName(String firstName, String lastName) {
92 | JSONObject body = new JSONObject();
93 | body.put("firstname", firstName);
94 | body.put("lastname", lastName);
95 |
96 | context.response = context.requestSetup()
97 | .header("Cookie", context.session.get("token").toString())
98 | .pathParam("bookingID", context.session.get("bookingID"))
99 | .body(body.toString())
100 | .when().patch(context.session.get("endpoint")+"/{bookingID}");
101 |
102 | BookingDetailsDTO bookingDetailsDTO = ResponseHandler.deserializedResponse(context.response, BookingDetailsDTO.class);
103 | assertNotNull("Booking not created", bookingDetailsDTO);
104 | assertEquals("First Name did not match", firstName, bookingDetailsDTO.getFirstname());
105 | assertEquals("Last Name did not match", lastName, bookingDetailsDTO.getLastname());
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/com/api/stepdefinition/ViewBookingDetailsStepdefinition.java:
--------------------------------------------------------------------------------
1 | package com.api.stepdefinition;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import org.apache.log4j.LogManager;
6 | import org.apache.log4j.Logger;
7 |
8 | import com.api.model.BookingDetailsDTO;
9 | import com.api.model.BookingID;
10 | import com.api.utils.ResponseHandler;
11 | import com.api.utils.TestContext;
12 |
13 | import io.cucumber.java.en.*;
14 | import io.restassured.module.jsv.JsonSchemaValidator;
15 |
16 | public class ViewBookingDetailsStepdefinition {
17 | private TestContext context;
18 | private static final Logger LOG = LogManager.getLogger(ViewBookingDetailsStepdefinition.class);
19 |
20 | public ViewBookingDetailsStepdefinition(TestContext context) {
21 | this.context = context;
22 | }
23 |
24 | @Given("user has access to endpoint {string}")
25 | public void userHasAccessToEndpoint(String endpoint) {
26 | context.session.put("endpoint", endpoint);
27 | }
28 |
29 | @When("user makes a request to view booking IDs")
30 | public void userMakesARequestToViewBookingIDs() {
31 | context.response = context.requestSetup().when().get(context.session.get("endpoint").toString());
32 | int bookingID = context.response.getBody().jsonPath().getInt("[0].bookingid");
33 | LOG.info("Booking ID: "+bookingID);
34 | assertNotNull("Booking ID not found!", bookingID);
35 | context.session.put("bookingID", bookingID);
36 | }
37 |
38 | @Then("user should get the response code {int}")
39 | public void userShpuldGetTheResponseCode(Integer statusCode) {
40 | assertEquals(Long.valueOf(statusCode), Long.valueOf(context.response.getStatusCode()));
41 | }
42 |
43 | @Then("user should see all the booking IDs")
44 | public void userShouldSeeAllTheBookingIDS() {
45 | BookingID[] bookingIDs = ResponseHandler.deserializedResponse(context.response, BookingID[].class);
46 | assertNotNull("Booking ID not found!!", bookingIDs);
47 | }
48 |
49 | @Then("user makes a request to view details of a booking ID")
50 | public void userMakesARequestToViewDetailsOfBookingID() {
51 | LOG.info("Session BookingID: "+context.session.get("bookingID"));
52 | context.response = context.requestSetup().pathParam("bookingID", context.session.get("bookingID"))
53 | .when().get(context.session.get("endpoint")+"/{bookingID}");
54 | BookingDetailsDTO bookingDetails = ResponseHandler.deserializedResponse(context.response, BookingDetailsDTO.class);
55 | assertNotNull("Booking Details not found!!", bookingDetails);
56 | context.session.put("firstname", bookingDetails.getFirstname());
57 | context.session.put("lastname", bookingDetails.getLastname());
58 | }
59 |
60 | @Given("user makes a request to view booking IDs from {string} to {string}")
61 | public void userMakesARequestToViewBookingFromTo(String checkin, String checkout) {
62 | context.response = context.requestSetup()
63 | .queryParams("checkin",checkin, "checkout", checkout)
64 | .when().get(context.session.get("endpoint").toString());
65 | }
66 |
67 | @Then("user makes a request to view all the booking IDs of that user name")
68 | public void userMakesARequestToViewBookingIDByUserName() {
69 | LOG.info("Session firstname: "+context.session.get("firstname"));
70 | LOG.info("Session lastname: "+context.session.get("lastname"));
71 | context.response = context.requestSetup()
72 | .queryParams("firstname", context.session.get("firstname"), "lastname", context.session.get("lastname"))
73 | .when().get(context.session.get("endpoint").toString());
74 | BookingID[] bookingIDs = ResponseHandler.deserializedResponse(context.response, BookingID[].class);
75 | assertNotNull("Booking ID not found!!", bookingIDs);
76 | }
77 |
78 | @Then("user validates the response with JSON schema {string}")
79 | public void userValidatesResponseWithJSONSchema(String schemaFileName) {
80 | context.response.then().assertThat().body(JsonSchemaValidator.matchesJsonSchemaInClasspath("schemas/"+schemaFileName));
81 | LOG.info("Successfully Validated schema from "+schemaFileName);
82 | }
83 |
84 | @When("user makes a request to check the health of booking service")
85 | public void userMakesARequestToCheckTheHealthOfBookingService() {
86 | context.response = context.requestSetup().get(context.session.get("endpoint").toString());
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/com/api/utils/ExcelUtils.java:
--------------------------------------------------------------------------------
1 | package com.api.utils;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | import org.apache.log4j.LogManager;
11 | import org.apache.log4j.Logger;
12 | import org.apache.poi.ss.usermodel.CellType;
13 | import org.apache.poi.xssf.usermodel.XSSFCell;
14 | import org.apache.poi.xssf.usermodel.XSSFRow;
15 | import org.apache.poi.xssf.usermodel.XSSFSheet;
16 | import org.apache.poi.xssf.usermodel.XSSFWorkbook;
17 |
18 | public class ExcelUtils {
19 | private static XSSFSheet excelSheet;
20 | private static XSSFWorkbook excelWorkbook;
21 | private static XSSFCell cell;
22 | private static XSSFRow row;
23 | private static String sheetPath = PropertiesFile.getProperty("test.data.path")+PropertiesFile.getProperty("excel.name");
24 | private static String sheetName = PropertiesFile.getProperty("sheet.name");
25 | private static final Logger LOG = LogManager.getLogger(ExcelUtils.class);
26 |
27 | private static void setExcelFile() throws IOException {
28 | LOG.info("Getting sheets from the workbook.");
29 | FileInputStream excelFile = new FileInputStream(new File(sheetPath).getAbsolutePath());
30 | excelWorkbook = new XSSFWorkbook(excelFile);
31 | excelSheet = excelWorkbook.getSheet(sheetName);
32 | }
33 |
34 | private static int getDataRow(String dataKey, int dataColumn) {
35 | int rowCount = excelSheet.getLastRowNum();
36 | for(int row=0; row<= rowCount; row++){
37 | if(ExcelUtils.getCellData(row, dataColumn).equalsIgnoreCase(dataKey)){
38 | return row;
39 | }
40 | }
41 | return 0;
42 | }
43 |
44 | private static String getCellData(int rowNumb, int colNumb) {
45 | cell = excelSheet.getRow(rowNumb).getCell(colNumb);
46 | //LOG.info("Getting cell data.");
47 | if(cell.getCellType() == CellType.NUMERIC) {
48 | cell.setCellType(CellType.STRING);
49 | }
50 | String cellData = cell.getStringCellValue();
51 | return cellData;
52 | }
53 |
54 | public static void setCellData(String result, int rowNumb, int colNumb, String sheetPath,String sheetName) throws Exception{
55 | try{
56 | row = excelSheet.getRow(rowNumb);
57 | cell = row.getCell(colNumb);
58 | LOG.info("Setting results into the excel sheet.");
59 | if(cell==null){
60 | cell = row.createCell(colNumb);
61 | cell.setCellValue(result);
62 | }
63 | else{
64 | cell.setCellValue(result);
65 | }
66 |
67 | LOG.info("Creating file output stream.");
68 | FileOutputStream fileOut = new FileOutputStream(sheetPath + sheetName);
69 | excelWorkbook.write(fileOut);
70 | fileOut.flush();
71 | fileOut.close();
72 |
73 | }catch(Exception exp){
74 | LOG.info("Exception occured in setCellData: "+exp);
75 | }
76 | }
77 |
78 | public static Map getData(String dataKey) throws Exception {
79 | Map dataMap = new HashMap();
80 | setExcelFile();
81 | int dataRow = getDataRow(dataKey.trim(), 0);
82 | LOG.info("Test Data Found in Row: "+dataRow);
83 | if (dataRow == 0) {
84 | throw new Exception("NO DATA FOUND for dataKey: "+dataKey);
85 | }
86 | int columnCount = excelSheet.getRow(dataRow).getLastCellNum();
87 | for(int i=0;i dataMap = new HashMap();
103 | dataMap = getData("updateBooking21");
104 | for(Map.Entry data: dataMap.entrySet()) {
105 | LOG.info(data.getKey()+ " ==> " + data.getValue());
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/com/api/utils/JsonReader.java:
--------------------------------------------------------------------------------
1 | package com.api.utils;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.FileReader;
6 | import java.io.IOException;
7 |
8 | import org.json.simple.JSONObject;
9 | import org.json.simple.parser.JSONParser;
10 | import org.json.simple.parser.ParseException;
11 |
12 | public class JsonReader {
13 |
14 | private static String dataPath = new File(PropertiesFile.getProperty("test.data.path")).getAbsolutePath()+File.separator;
15 | private static JSONParser parser = new JSONParser();
16 | private static Object body;
17 |
18 | public static String getRequestBody(String jsonFileName, String jsonKey) {
19 | try {
20 | body = ((JSONObject)parser.parse(new FileReader(dataPath+jsonFileName))).get(jsonKey);
21 | if (body == null) {
22 | throw new RuntimeException("NO DATA FOUND in JSON file '" + jsonFileName +"' for key '"+jsonKey+"'");
23 | }
24 | } catch (FileNotFoundException e) {
25 | throw new RuntimeException("JSON file not found at path: " + dataPath+jsonFileName);
26 | } catch (IOException e) {
27 | throw new RuntimeException("IOException while reading file: " + jsonFileName);
28 | } catch (ParseException e) {
29 | throw new RuntimeException("Parse Exception occured while Parsing: " + jsonFileName);
30 | }
31 | return body.toString();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/api/utils/MyTestListener.java:
--------------------------------------------------------------------------------
1 | package com.api.utils;
2 |
3 | import org.apache.log4j.LogManager;
4 | import org.apache.log4j.Logger;
5 |
6 | import io.cucumber.plugin.ConcurrentEventListener;
7 | import io.cucumber.plugin.event.EventPublisher;
8 | import io.cucumber.plugin.event.Result;
9 | import io.cucumber.plugin.event.Status;
10 | import io.cucumber.plugin.event.TestCase;
11 | import io.cucumber.plugin.event.TestCaseFinished;
12 |
13 | public class MyTestListener implements ConcurrentEventListener {
14 | private static final Logger LOG = LogManager.getLogger(MyTestListener.class);
15 |
16 | @Override
17 | public void setEventPublisher(EventPublisher publisher) {
18 | publisher.registerHandlerFor(TestCaseFinished.class, this::handleTestCaseFinished);
19 | }
20 |
21 | private void handleTestCaseFinished(TestCaseFinished event) {
22 | TestCase testCase = event.getTestCase();
23 | Result result = event.getResult();
24 | Status status = result.getStatus();
25 | Throwable error = result.getError();
26 | String scenarioName = testCase.getName();
27 | if(error != null) {
28 | LOG.info(error);
29 | }
30 | LOG.info("*****************************************************************************************");
31 | LOG.info(" Scenario: "+scenarioName+" --> "+status.name());
32 | LOG.info("*****************************************************************************************");
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/java/com/api/utils/PropertiesFile.java:
--------------------------------------------------------------------------------
1 | package com.api.utils;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.FileNotFoundException;
6 | import java.io.IOException;
7 | import java.util.Properties;
8 |
9 | import org.apache.log4j.LogManager;
10 | import org.apache.log4j.Logger;
11 |
12 | public class PropertiesFile {
13 |
14 | private static final Logger LOG = LogManager.getLogger(PropertiesFile.class);
15 | private static FileInputStream fis;
16 | private static Properties prop = null;
17 |
18 | public static String getProperty(String property) {
19 |
20 | try {
21 | fis = new FileInputStream(new File("config.properties"));
22 | prop = new Properties();
23 | prop.load(fis);
24 | } catch(FileNotFoundException fnfe) {
25 | LOG.error("Properties File Not Found", fnfe);
26 | } catch(IOException ioe) {
27 | LOG.error("IO Exception while loading Properties File", ioe);
28 | } finally {
29 | try {
30 | fis.close();
31 | } catch (IOException e) {
32 | LOG.error("IO Exception while closing file input stream", e);
33 | }
34 | }
35 | return prop.getProperty(property).trim();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/api/utils/ResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.api.utils;
2 |
3 | import java.io.IOException;
4 |
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 |
7 | import io.restassured.response.Response;
8 |
9 | public class ResponseHandler {
10 |
11 | public static T deserializedResponse(Response response, Class T ){
12 | ObjectMapper mapper = new ObjectMapper();
13 | T responseDeserialized = null;
14 | try {
15 | responseDeserialized = (T) mapper.readValue(response.asString(), T);
16 | String jsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(responseDeserialized); // Pretty print JSON
17 | System.out.println("Handling Response: \n"+responseDeserialized.toString());
18 | } catch (IOException e) {
19 | e.printStackTrace(System.out);
20 | }
21 | return responseDeserialized;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/api/utils/RestAssuredRequestFilter.java:
--------------------------------------------------------------------------------
1 | package com.api.utils;
2 |
3 | import org.apache.log4j.LogManager;
4 | import org.apache.log4j.Logger;
5 |
6 | import io.restassured.filter.Filter;
7 | import io.restassured.filter.FilterContext;
8 | import io.restassured.response.Response;
9 | import io.restassured.specification.FilterableRequestSpecification;
10 | import io.restassured.specification.FilterableResponseSpecification;
11 |
12 | public class RestAssuredRequestFilter implements Filter {
13 | private static final Logger LOG = LogManager.getLogger(RestAssuredRequestFilter.class);
14 |
15 | @Override
16 | public Response filter(FilterableRequestSpecification requestSpec, FilterableResponseSpecification responseSpec, FilterContext ctx) {
17 | Response response = ctx.next(requestSpec, responseSpec);
18 | LOG.info("-----------------------------------------------------------------------------------------");
19 | LOG.info(" Request Method => " + requestSpec.getMethod() +
20 | "\n Request URI => " + requestSpec.getURI() +
21 | "\n Request Header =>\n" + requestSpec.getHeaders() +
22 | "\n Request Body => " + requestSpec.getBody() +
23 | "\n\n Response Status => "+ response.getStatusLine() +
24 | "\n Response Header =>\n"+ response.getHeaders() +
25 | "\n Response Body => " + response.getBody().prettyPrint());
26 | LOG.info("-----------------------------------------------------------------------------------------");
27 | return response;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/api/utils/TestContext.java:
--------------------------------------------------------------------------------
1 | package com.api.utils;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import com.github.dzieciou.testing.curl.CurlRestAssuredConfigFactory;
7 | import com.github.dzieciou.testing.curl.Options;
8 |
9 | import io.restassured.RestAssured;
10 | import io.restassured.config.RestAssuredConfig;
11 | import io.restassured.response.Response;
12 | import io.restassured.specification.RequestSpecification;
13 |
14 | public class TestContext {
15 |
16 | public Response response;
17 | public Map session = new HashMap();
18 | private static final String CONTENT_TYPE = PropertiesFile.getProperty("content.type");
19 |
20 | public RequestSpecification requestSetup() {
21 | RestAssured.reset();
22 | Options options = Options.builder().logStacktrace().build();
23 | RestAssuredConfig config = CurlRestAssuredConfigFactory.createConfig(options);
24 | RestAssured.baseURI = PropertiesFile.getProperty("baseURL");
25 | return RestAssured.given()
26 | .config(config)
27 | .filter(new RestAssuredRequestFilter())
28 | .contentType(CONTENT_TYPE)
29 | .accept(CONTENT_TYPE);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/resources/extent-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | dark
7 |
8 |
9 | UTF-8
10 |
11 |
12 | http
13 |
14 | Booker API Report
15 |
16 | Execution Report
17 |
18 |
19 | top
20 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO, STDOUT, file, HTML
2 |
3 | log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
4 | log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
5 | log4j.appender.STDOUT.layout.ConversionPattern=%d{dd-MM-yyyy HH:mm:ss} %-5p %c{1}:%L - %m%n
6 |
7 | log4j.appender.file=org.apache.log4j.RollingFileAppender
8 | log4j.appender.file.File=target/logs/execution.log
9 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
10 | log4j.appender.file.layout.ConversionPattern=%d{dd-MM-yyyy HH:mm:ss} %-5p %c{1}:%L - %m%n
--------------------------------------------------------------------------------
/src/test/java/com/api/test/TestRunner.java:
--------------------------------------------------------------------------------
1 | package com.api.test;
2 |
3 | import org.junit.runner.RunWith;
4 |
5 | import io.cucumber.junit.Cucumber;
6 | import io.cucumber.junit.CucumberOptions;
7 | import io.cucumber.junit.CucumberOptions.SnippetType;
8 |
9 | @RunWith(Cucumber.class)
10 | @CucumberOptions(
11 | plugin = {"pretty:target/cucumber/cucumber.txt",
12 | "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:",
13 | //"html:target/cucumber/report",
14 | "json:target/cucumber/cucumber.json",
15 | "com.api.utils.MyTestListener"
16 | }
17 | ,features= {"src/test/resources/features"}
18 | ,glue = {"com.api.stepdefinition"}
19 | //,dryRun = true
20 | ,monochrome = true
21 | ,snippets = SnippetType.CAMELCASE
22 | ,tags = "@bookerAPI"
23 | //,publish = true
24 | )
25 | public class TestRunner {
26 |
27 | }
--------------------------------------------------------------------------------
/src/test/resources/cucumber.properties:
--------------------------------------------------------------------------------
1 | cucumber.publish.quiet=true
--------------------------------------------------------------------------------
/src/test/resources/data/bookingBody.json:
--------------------------------------------------------------------------------
1 | {
2 | "createBooking1": {
3 | "firstname": "Sherlock",
4 | "lastname": "Holmes",
5 | "totalprice": "2500",
6 | "depositpaid": "true",
7 | "bookingdates": {
8 | "checkin":"2021-05-15",
9 | "checkout":"2021-06-02"
10 | },
11 | "additionalneeds":"Snacks"
12 | },
13 | "createBooking2": {
14 | "firstname": "James",
15 | "lastname": "Bond",
16 | "totalprice": "70007",
17 | "depositpaid": "false",
18 | "bookingdates": {
19 | "checkin":"2020-11-10",
20 | "checkout":"2020-11-20"
21 | },
22 | "additionalneeds":"High Tea"
23 | },
24 | "updateBooking1": {
25 | "firstname": "Clark",
26 | "lastname": "Kent",
27 | "totalprice": "12321",
28 | "depositpaid": "true",
29 | "bookingdates": {
30 | "checkin":"2021-11-10",
31 | "checkout":"2021-11-20"
32 | },
33 | "additionalneeds":"Super Tea"
34 | },
35 | "updateBooking2": {
36 | "firstname": "Bruce",
37 | "lastname": "Wayne",
38 | "totalprice": "35007",
39 | "depositpaid": "false",
40 | "bookingdates": {
41 | "checkin":"2021-09-10",
42 | "checkout":"2021-10-20"
43 | },
44 | "additionalneeds":"Bat Dish"
45 | }
46 | }
--------------------------------------------------------------------------------
/src/test/resources/data/testData.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VinayKumarBM/API-Cucumber/c689d37a71f907d1b14b128f2aa02fd1b38896d1/src/test/resources/data/testData.xlsx
--------------------------------------------------------------------------------
/src/test/resources/extent.properties:
--------------------------------------------------------------------------------
1 | extent.reporter.spark.class=com.aventstack.extentreports.reporter.ExtentSparkReporter
2 | extent.reporter.json.class=com.aventstack.extentreports.reporter.JsonFormatter
3 | extent.reporter.pdf.class=tech.grasshopper.pdf.extent.ExtentPDFCucumberReporter
4 |
5 | extent.reporter.spark.start=true
6 | extent.reporter.json.start=false
7 | extent.reporter.pdf.start=true
8 |
9 | extent.reporter.spark.out=target/report/ExtentSpark.html
10 | extent.reporter.json.out=target/report/ExtentJson.json
11 | extent.reporter.pdf.out=target/report/ExtentPdf.pdf
12 |
13 | extent.reporter.spark.config=src/main/resources/extent-config.xml
14 | extent.reporter.logger.config=src/main/resources/extent-config.xml
15 |
16 | extent.reporter.spark.vieworder=dashboard,test,category,exception,author,device,log
17 |
18 | systeminfo.OS=Windows
19 | systeminfo.URL=https://restful-booker.herokuapp.com
20 | systeminfo.Owner=Vinay Kumar B M
21 | systeminfo.Role=Automation Tester
--------------------------------------------------------------------------------
/src/test/resources/features/CreateBooking.feature:
--------------------------------------------------------------------------------
1 | @bookerAPI @createBooking
2 | Feature: To create a new booking in restful-booker
3 |
4 | @createBookingDataTable
5 | Scenario Outline: To create new booking using cucumber Data Table
6 | Given user has access to endpoint "/booking"
7 | When user creates a booking
8 | | firstname | lastname | totalprice | depositpaid | checkin | checkout | additionalneeds |
9 | | | | | | | | |
10 | Then user should get the response code 200
11 | And user validates the response with JSON schema "createBookingSchema.json"
12 |
13 | Examples:
14 | | firstname | lastname | totalprice | depositpaid | checkin | checkout | additionalneeds |
15 | | John | Doe | 1200 | true | 2021-05-05 | 2021-05-15 | Breakfast |
16 | | Jane | Doe | 2400 | false | 2021-06-01 | 2021-07-10 | Dinner |
17 |
18 | @createBookingFromExcel
19 | Scenario Outline: To create new booking using Excel data
20 | Given user has access to endpoint "/booking"
21 | When user creates a booking using data "" from Excel
22 | Then user should get the response code 200
23 | And user validates the response with JSON schema from Excel
24 |
25 | Examples:
26 | | dataKey |
27 | | createBooking1 |
28 | | createBooking2 |
29 |
30 | @createBookingFromJSON
31 | Scenario Outline: To create new booking using JSON data
32 | Given user has access to endpoint "/booking"
33 | When user creates a booking using data "" from JSON file ""
34 | Then user should get the response code 200
35 | And user validates the response with JSON schema "createBookingSchema.json"
36 |
37 | Examples:
38 | | dataKey | JSONFile |
39 | | createBooking1 | bookingBody.json |
40 | | createBooking2 | bookingBody.json |
41 |
--------------------------------------------------------------------------------
/src/test/resources/features/DeleteBooking.feature:
--------------------------------------------------------------------------------
1 | @bookerAPI @deleteBooking
2 | Feature: To delete a booking in restful-booker
3 |
4 | Background: create an auth token
5 | Given user has access to endpoint "/auth"
6 | When user creates a auth token with credential "admin" & "password123"
7 | Then user should get the response code 200
8 |
9 | @deleteBookingIDs
10 | Scenario: To delete a booking
11 | Given user has access to endpoint "/booking"
12 | And user makes a request to view booking IDs
13 | When user makes a request to delete booking with basic auth "admin" & "password123"
14 | Then user should get the response code 201
15 |
16 | @e2eTest
17 | Scenario Outline: To perform a CURD operation on restful-booker
18 | Given user has access to endpoint "/booking"
19 | When user creates a booking
20 | | firstname | lastname | totalprice | depositpaid | checkin | checkout | additionalneeds |
21 | | | | | | | | |
22 | Then user should get the response code 200
23 | And user validates the response with JSON schema "createBookingSchema.json"
24 | And user updates the details of a booking
25 | | firstname | lastname | totalprice | depositpaid | checkin | checkout | additionalneeds |
26 | | | | | | | | |
27 | And user should get the response code 200
28 | And user validates the response with JSON schema "bookingDetailsSchema.json"
29 | And user makes a request to view details of a booking ID
30 | And user should get the response code 200
31 | And user validates the response with JSON schema "bookingDetailsSchema.json"
32 | And user makes a request to delete booking with basic auth "admin" & "password123"
33 | And user should get the response code 201
34 |
35 | Examples:
36 | | firstname | lastname | totalprice | depositpaid | checkin | checkout | additionalneeds |
37 | | John | Doe | 1200 | true | 2021-05-05 | 2021-05-15 | Breakfast |
38 |
--------------------------------------------------------------------------------
/src/test/resources/features/UpdateBooking.feature:
--------------------------------------------------------------------------------
1 | @bookerAPI @updateBooking
2 | Feature: To update a booking in restful-booker
3 |
4 | Background: create an auth token
5 | Given user has access to endpoint "/auth"
6 | When user creates a auth token with credential "admin" & "password123"
7 | Then user should get the response code 200
8 |
9 | @updateBookingDataTable
10 | Scenario Outline: To update a booking using cucumber Data Table
11 | Given user has access to endpoint "/booking"
12 | When user makes a request to view booking IDs
13 | And user updates the details of a booking
14 | | firstname | lastname | totalprice | depositpaid | checkin | checkout | additionalneeds |
15 | | | | | | | | |
16 | Then user should get the response code 200
17 | And user validates the response with JSON schema "bookingDetailsSchema.json"
18 |
19 | Examples:
20 | | firstname | lastname | totalprice | depositpaid | checkin | checkout | additionalneeds |
21 | | John | Rambo | 10000 | true | 2021-05-15 | 2021-06-11 | Breakfast |
22 | | Rocky | Balboa | 2006 | false | 2021-06-01 | 2021-07-10 | Dinner |
23 |
24 | @updateBookingFromExcel
25 | Scenario Outline: To create and update a new booking using Excel data
26 | Given user has access to endpoint "/booking"
27 | And user creates a booking using data "" from Excel
28 | When user updates the booking details using data "" from Excel
29 | Then user should get the response code 200
30 | And user validates the response with JSON schema from Excel
31 |
32 | Examples:
33 | | createKey | updateKey |
34 | | createBooking1 | updateBooking1 |
35 | | createBooking2 | updateBooking2 |
36 |
37 | @updateBookingFromJSON
38 | Scenario Outline: To update a booking using JSON data
39 | Given user has access to endpoint "/booking"
40 | When user makes a request to view booking IDs
41 | And user updates the booking details using data "" from JSON file ""
42 | Then user should get the response code 200
43 | And user validates the response with JSON schema "bookingDetailsSchema.json"
44 |
45 | Examples:
46 | | dataKey | JSONFile |
47 | | updateBooking1 | bookingBody.json |
48 | | updateBooking2 | bookingBody.json |
49 |
50 | @partialUpdateBooking
51 | Scenario: To partially update a booking
52 | Given user has access to endpoint "/booking"
53 | When user makes a request to view booking IDs
54 | And user makes a request to update first name "John" & Last name "Wick"
55 | Then user should get the response code 200
56 | And user validates the response with JSON schema "bookingDetailsSchema.json"
--------------------------------------------------------------------------------
/src/test/resources/features/ViewBookingDetails.feature:
--------------------------------------------------------------------------------
1 | @bookerAPI @viewBooking
2 | Feature: To view the restful-booker booking details
3 |
4 | @viewAllBookingIDs
5 | Scenario: To view all the booking IDs
6 | Given user has access to endpoint "/booking"
7 | When user makes a request to view booking IDs
8 | Then user should get the response code 200
9 | And user should see all the booking IDs
10 |
11 | @viewBookingDetails
12 | Scenario: To view booking details
13 | Given user has access to endpoint "/booking"
14 | When user makes a request to view booking IDs
15 | And user makes a request to view details of a booking ID
16 | Then user should get the response code 200
17 | And user validates the response with JSON schema "bookingDetailsSchema.json"
18 |
19 | @viewByBookingDates
20 | Scenario Outline: To view all the booking IDs by booking dates
21 | Given user has access to endpoint "/booking"
22 | When user makes a request to view booking IDs from "" to ""
23 | Then user should get the response code 200
24 | And user should see all the booking IDs
25 |
26 | Examples:
27 | | checkin | checkout |
28 | | 2018-01-01 | 2021-12-31 |
29 | | 2010-01-01 | 2020-12-31 |
30 |
31 | @viewBookingByName
32 | Scenario: To view all the booking IDs by booking names
33 | Given user has access to endpoint "/booking"
34 | When user makes a request to view booking IDs
35 | Then user should see all the booking IDs
36 | And user makes a request to view details of a booking ID
37 | And user makes a request to view all the booking IDs of that user name
38 | And user should get the response code 200
39 | And user should see all the booking IDs
40 |
41 | @healthCheck
42 | Scenario: To confirm whether the API is up and running
43 | Given user has access to endpoint "/ping"
44 | When user makes a request to check the health of booking service
45 | Then user should get the response code 201
46 |
--------------------------------------------------------------------------------
/src/test/resources/schemas/bookSchema.json:
--------------------------------------------------------------------------------
1 | {
2 | "definitions": {},
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "$id": "http://example.com/root.json",
5 | "type": "object",
6 | "title": "The Root Schema",
7 | "required": [
8 | "title",
9 | "body",
10 | "userId",
11 | "id"
12 | ],
13 | "properties": {
14 | "title": {
15 | "$id": "#/properties/title",
16 | "type": "string",
17 | "title": "The Title Schema",
18 | "default": "",
19 | "examples": [
20 | "Game of Throne"
21 | ],
22 | "pattern": "^(.*)$"
23 | },
24 | "body": {
25 | "$id": "#/properties/body",
26 | "type": "string",
27 | "title": "The Body Schema",
28 | "default": "",
29 | "examples": [
30 | "Here will be description of the Book"
31 | ],
32 | "pattern": "^(.*)$"
33 | },
34 | "userId": {
35 | "$id": "#/properties/userId",
36 | "type": "string",
37 | "title": "The Userid Schema",
38 | "default": "",
39 | "examples": [
40 | "911"
41 | ],
42 | "pattern": "^(.*)$"
43 | },
44 | "id": {
45 | "$id": "#/properties/id",
46 | "type": "integer",
47 | "title": "The Id Schema",
48 | "default": 0,
49 | "examples": [
50 | 101
51 | ]
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/src/test/resources/schemas/bookingDetailsSchema.json:
--------------------------------------------------------------------------------
1 | {
2 | "definitions": {},
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "$id": "https://example.com/object1617469812.json",
5 | "title": "Root",
6 | "type": "object",
7 | "required": [
8 | "firstname",
9 | "lastname",
10 | "totalprice",
11 | "depositpaid",
12 | "bookingdates"
13 | ],
14 | "properties": {
15 | "firstname": {
16 | "$id": "#root/firstname",
17 | "title": "Firstname",
18 | "type": "string",
19 | "default": "",
20 | "pattern": "^.*$"
21 | },
22 | "lastname": {
23 | "$id": "#root/lastname",
24 | "title": "Lastname",
25 | "type": "string",
26 | "default": "",
27 | "pattern": "^.*$"
28 | },
29 | "totalprice": {
30 | "$id": "#root/totalprice",
31 | "title": "Totalprice",
32 | "type": "integer",
33 | "default": 0
34 | },
35 | "depositpaid": {
36 | "$id": "#root/depositpaid",
37 | "title": "Depositpaid",
38 | "type": "boolean",
39 | "default": true
40 | },
41 | "bookingdates": {
42 | "$id": "#root/bookingdates",
43 | "title": "Bookingdates",
44 | "type": "object",
45 | "required": [
46 | "checkin",
47 | "checkout"
48 | ],
49 | "properties": {
50 | "checkin": {
51 | "$id": "#root/bookingdates/checkin",
52 | "title": "Checkin",
53 | "type": "string",
54 | "default": "",
55 | "pattern": "^.*$"
56 | },
57 | "checkout": {
58 | "$id": "#root/bookingdates/checkout",
59 | "title": "Checkout",
60 | "type": "string",
61 | "default": "",
62 | "pattern": "^.*$"
63 | }
64 | }
65 | }
66 | ,
67 | "additionalneeds": {
68 | "$id": "#root/additionalneeds",
69 | "title": "Additionalneeds",
70 | "type": "string",
71 | "default": "",
72 | "pattern": "^.*$"
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/src/test/resources/schemas/createBookingSchema.json:
--------------------------------------------------------------------------------
1 | {
2 | "definitions": {},
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "$id": "https://example.com/object1617473424.json",
5 | "title": "Root",
6 | "type": "object",
7 | "required": [
8 | "bookingid",
9 | "booking"
10 | ],
11 | "properties": {
12 | "bookingid": {
13 | "$id": "#root/bookingid",
14 | "title": "Bookingid",
15 | "type": "integer",
16 | "default": 0
17 | },
18 | "booking": {
19 | "$id": "#root/booking",
20 | "title": "Booking",
21 | "type": "object",
22 | "required": [
23 | "firstname",
24 | "lastname",
25 | "totalprice",
26 | "depositpaid",
27 | "bookingdates",
28 | "additionalneeds"
29 | ],
30 | "properties": {
31 | "firstname": {
32 | "$id": "#root/booking/firstname",
33 | "title": "Firstname",
34 | "type": "string",
35 | "default": "",
36 | "pattern": "^.*$"
37 | },
38 | "lastname": {
39 | "$id": "#root/booking/lastname",
40 | "title": "Lastname",
41 | "type": "string",
42 | "default": "",
43 | "pattern": "^.*$"
44 | },
45 | "totalprice": {
46 | "$id": "#root/booking/totalprice",
47 | "title": "Totalprice",
48 | "type": "integer",
49 | "default": 0
50 | },
51 | "depositpaid": {
52 | "$id": "#root/booking/depositpaid",
53 | "title": "Depositpaid",
54 | "type": "boolean",
55 | "default": true
56 | },
57 | "bookingdates": {
58 | "$id": "#root/booking/bookingdates",
59 | "title": "Bookingdates",
60 | "type": "object",
61 | "required": [
62 | "checkin",
63 | "checkout"
64 | ],
65 | "properties": {
66 | "checkin": {
67 | "$id": "#root/booking/bookingdates/checkin",
68 | "title": "Checkin",
69 | "type": "string",
70 | "default": "",
71 | "pattern": "^.*$"
72 | },
73 | "checkout": {
74 | "$id": "#root/booking/bookingdates/checkout",
75 | "title": "Checkout",
76 | "type": "string",
77 | "default": "",
78 | "pattern": "^.*$"
79 | }
80 | }
81 | }
82 | ,
83 | "additionalneeds": {
84 | "$id": "#root/booking/additionalneeds",
85 | "title": "Additionalneeds",
86 | "type": "string",
87 | "default": "",
88 | "pattern": "^.*$"
89 | }
90 | }
91 | }
92 |
93 | }
94 | }
--------------------------------------------------------------------------------
/src/test/resources/schemas/userSchema.json:
--------------------------------------------------------------------------------
1 | {
2 | "definitions": {},
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "$id": "http://example.com/root.json",
5 | "type": "object",
6 | "title": "The Root Schema",
7 | "required": [
8 | "name",
9 | "job",
10 | "id",
11 | "createdAt"
12 | ],
13 | "properties": {
14 | "name": {
15 | "$id": "#/properties/name",
16 | "type": "string",
17 | "title": "The Name Schema",
18 | "default": "",
19 | "examples": [
20 | "Tester"
21 | ],
22 | "pattern": "^(.*)$"
23 | },
24 | "job": {
25 | "$id": "#/properties/job",
26 | "type": "string",
27 | "title": "The Job Schema",
28 | "default": "",
29 | "examples": [
30 | "Automation"
31 | ],
32 | "pattern": "^(.*)$"
33 | },
34 | "id": {
35 | "$id": "#/properties/id",
36 | "type": "string",
37 | "title": "The Id Schema",
38 | "default": "",
39 | "examples": [
40 | "624"
41 | ],
42 | "pattern": "^(.*)$"
43 | },
44 | "createdAt": {
45 | "$id": "#/properties/createdAt",
46 | "type": "string",
47 | "title": "The Createdat Schema",
48 | "default": "",
49 | "examples": [
50 | "2019-03-08T16:34:10.744Z"
51 | ],
52 | "pattern": "^(.*)$"
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------