├── .gitignore
├── configuration.properties
├── pom.xml
├── readme.md
└── src
└── test
├── java
└── com
│ └── cybertek
│ └── library
│ ├── pages
│ ├── BasePage.java
│ ├── BooksPage.java
│ ├── DashBoardPage.java
│ ├── LoginPage.java
│ └── UsersPage.java
│ ├── pojos
│ ├── Book.java
│ └── User.java
│ ├── runners
│ ├── CukesRunner.java
│ └── FailedTestRunner.java
│ ├── step_definitions
│ ├── BaseStep.java
│ ├── BooksStepDefs.java
│ ├── DashboardNavigationStepDefs.java
│ ├── Hooks.java
│ ├── LoginStepDefs.java
│ └── UserStepDefs.java
│ └── utilities
│ ├── api
│ ├── AuthenticationUtility.java
│ ├── Endpoints.java
│ ├── LibrarianAuthenticationUtility.java
│ └── StudentAuthenticationUtility.java
│ ├── common
│ ├── Encoder.java
│ ├── Environment.java
│ ├── LibraryConstants.java
│ └── LibraryUserUtility.java
│ ├── db
│ └── DBUtils.java
│ └── ui
│ ├── BrowserUtils.java
│ ├── Driver.java
│ └── Pages.java
└── resources
├── env
├── qa1.properties
├── qa2.properties
└── qa3.properties
├── features
├── AddUserAPITests.feature
├── BookInformationValidation.feature
├── PageNavigation.feature
├── SearchResults.feature
└── UserTable.feature
└── test-data
├── Library QA 1 user data.pdf
└── Library QA 2 user data.xlsx
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/
2 | *.iml
3 | target
4 | .DS_Store
5 | test-output
6 |
--------------------------------------------------------------------------------
/configuration.properties:
--------------------------------------------------------------------------------
1 | browser=chrome
2 | env=qa1
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.syslibrary
8 | syslibrary-cucumber-framework
9 | 1.0-SNAPSHOT
10 |
11 | 1.8
12 | 1.8
13 | UTF-8
14 | UTF-8
15 |
16 |
17 |
18 | org.seleniumhq.selenium
19 | selenium-java
20 | 3.141.59
21 |
22 |
23 | io.cucumber
24 | cucumber-java
25 | 5.6.0
26 |
27 |
28 | io.cucumber
29 | cucumber-junit
30 | 5.6.0
31 |
32 |
33 | io.github.bonigarcia
34 | webdrivermanager
35 | 3.8.1
36 |
37 |
38 | mysql
39 | mysql-connector-java
40 | 8.0.18
41 |
42 |
43 | io.rest-assured
44 | rest-assured
45 | 4.3.0
46 |
47 |
48 | com.github.javafaker
49 | javafaker
50 | 1.0.2
51 |
52 |
53 | com.google.code.gson
54 | gson
55 | 2.8.6
56 |
57 |
58 |
59 |
60 |
61 |
62 | org.apache.maven.plugins
63 | maven-surefire-plugin
64 | 3.0.0-M4
65 |
66 |
67 | **/CukesRunner.java
68 |
69 | true
70 | methods
71 | 3
72 | false
73 | perthread
74 |
75 |
76 |
77 | net.masterthought
78 | maven-cucumber-reporting
79 | 5.0.0
80 |
81 |
82 | execution
83 | verify
84 |
85 | generate
86 |
87 |
88 | Cucumber HTML Reports
89 | ${project.build.directory}
90 | ${project.build.directory}
91 |
92 | **/cucumber*.json
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cybertek-Mentors/syslibrary-cucumber-framework/06eaff8452df8c9be61332cd389fc59e4abfe20f/readme.md
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/pages/BasePage.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.pages;
2 |
3 | import com.cybertek.library.utilities.ui.Driver;
4 | import org.openqa.selenium.WebElement;
5 | import org.openqa.selenium.support.FindBy;
6 | import org.openqa.selenium.support.PageFactory;
7 |
8 | public abstract class BasePage {
9 | public BasePage() {
10 | PageFactory.initElements(Driver.getDriver(), this);
11 | }
12 |
13 | @FindBy(xpath = "//span[@class='title'][.='Users']")
14 | public WebElement users;
15 |
16 | @FindBy(xpath = "//span[@class='title'][.='Dashboard']")
17 | public WebElement dashboard;
18 |
19 | @FindBy(xpath = "//span[@class='title'][.='Books']")
20 | public WebElement books;
21 |
22 | @FindBy(tagName = "h3")
23 | public WebElement pageHeader;
24 |
25 | @FindBy(css = "#navbarDropdown>span")
26 | public WebElement accountHolderName;
27 |
28 | @FindBy(linkText = "Log Out")
29 | public WebElement logOutLink;
30 |
31 | public void logOut(){
32 | accountHolderName.click();
33 | logOutLink.click();
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/pages/BooksPage.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.pages;
2 |
3 | import com.cybertek.library.utilities.ui.Driver;
4 | import org.openqa.selenium.By;
5 | import org.openqa.selenium.WebElement;
6 | import org.openqa.selenium.support.FindBy;
7 | import org.openqa.selenium.support.ui.Select;
8 |
9 | import java.util.List;
10 |
11 | public class BooksPage extends BasePage {
12 |
13 | @FindBy(xpath = "//table/tbody/tr")
14 | public List allRows;
15 |
16 | @FindBy(tagName = "input")
17 | public WebElement search;
18 |
19 | @FindBy(css = "[href='tpl/add-book.html']")
20 | public WebElement addBook;
21 |
22 | @FindBy(name = "name")
23 | public WebElement bookName;
24 |
25 | @FindBy(name = "isbn")
26 | public WebElement isbn;
27 |
28 | @FindBy(name = "year")
29 | public WebElement year;
30 |
31 | @FindBy(xpath = "(//input[@type='text'])[4]")
32 | public WebElement author;
33 |
34 | @FindBy(id = "description")
35 | public WebElement description;
36 |
37 | @FindBy(id = "book_group_id")
38 | public WebElement categoryElement;
39 |
40 | @FindBy(id = "book_categories")
41 | public WebElement mainCategoryElement;
42 |
43 | public WebElement editBook(String book) {
44 | String xpath = "//td[3][.='" + book + "']/../td/a";
45 | return Driver.getDriver().findElement(By.xpath(xpath));
46 | }
47 |
48 | public Select categoryList() {
49 | return new Select(categoryElement);
50 | }
51 |
52 | public Select mainCategoryList() {
53 | return new Select(mainCategoryElement);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/pages/DashBoardPage.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.pages;
2 |
3 | import org.openqa.selenium.WebElement;
4 | import org.openqa.selenium.support.FindBy;
5 |
6 | public class DashBoardPage extends BasePage {
7 | @FindBy(id = "user_count")
8 | public WebElement userCount;
9 |
10 | @FindBy(id = "book_count")
11 | public WebElement bookCount;
12 |
13 | @FindBy(id = "borrowed_books")
14 | public WebElement borrowedBooksCount;
15 | }
16 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/pages/LoginPage.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.pages;
2 |
3 | import com.cybertek.library.utilities.ui.Driver;
4 | import org.openqa.selenium.WebElement;
5 | import org.openqa.selenium.support.FindBy;
6 | import org.openqa.selenium.support.PageFactory;
7 |
8 | public class LoginPage {
9 | public LoginPage() {
10 | PageFactory.initElements(Driver.getDriver(), this);
11 | }
12 |
13 | @FindBy(id = "inputEmail")
14 | public WebElement email;
15 |
16 | @FindBy(id = "inputPassword")
17 | public WebElement password;
18 |
19 | @FindBy(tagName = "button")
20 | public WebElement signIn;
21 |
22 | public void login(String email, String password) {
23 | this.email.sendKeys(email);
24 | this.password.sendKeys(password);
25 | signIn.click();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/pages/UsersPage.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.pages;
2 |
3 | import org.openqa.selenium.WebElement;
4 | import org.openqa.selenium.support.FindBy;
5 | import org.openqa.selenium.support.ui.Select;
6 |
7 | import java.util.List;
8 |
9 | public class UsersPage extends BasePage {
10 | @FindBy(name = "tbl_users_length")
11 | public WebElement showRecords;
12 |
13 | @FindBy(xpath = "//table/tbody/tr")
14 | public List allRows;
15 |
16 | @FindBy(tagName = "input")
17 | public WebElement search;
18 |
19 | @FindBy(xpath = "//table/tbody/tr/td[2]")
20 | public List allUserIds;
21 |
22 | @FindBy(xpath = "//table/tbody/tr/td[3]")
23 | public List allFullNames;
24 |
25 | @FindBy(xpath = "//table/tbody/tr/td[4]")
26 | public List allEmails;
27 |
28 | @FindBy(tagName = "th")
29 | public List columnNames;
30 |
31 | @FindBy(css = "a.btn-lg")
32 | public WebElement addUsers;
33 |
34 | @FindBy(name = "full_name")
35 | public WebElement fullName;
36 |
37 | @FindBy(name = "password")
38 | public WebElement password;
39 |
40 | @FindBy(name = "email")
41 | public WebElement email;
42 |
43 | @FindBy(id = "address")
44 | public WebElement address;
45 |
46 | @FindBy(id = "user_group_id")
47 | public WebElement group;
48 |
49 | @FindBy(id = "status")
50 | public WebElement status;
51 |
52 | @FindBy(css="a.page-link:not([title])")
53 | public List pagesList;
54 |
55 | public Select getShowRecords() {
56 | return new Select(showRecords);
57 | }
58 |
59 | public Select getGroup(){
60 | return new Select(group);
61 | }
62 |
63 | public Select getStatus(){
64 | return new Select(status);
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/pojos/Book.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.pojos;
2 |
3 | public class Book {
4 | private String name;
5 | private String author;
6 | private String year;
7 | private String category;
8 | private String isbn;
9 | private String description;
10 |
11 | public Book(String name, String author, String year) {
12 | this.name = name;
13 | this.author = author;
14 | this.year = year;
15 | }
16 |
17 | public String getName() {
18 | return name;
19 | }
20 |
21 | public void setName(String name) {
22 | this.name = name;
23 | }
24 |
25 | public String getAuthor() {
26 | return author;
27 | }
28 |
29 | public void setAuthor(String author) {
30 | this.author = author;
31 | }
32 |
33 | public String getYear() {
34 | return year;
35 | }
36 |
37 | public void setYear(String year) {
38 | this.year = year;
39 | }
40 |
41 | public String getCategory() {
42 | return category;
43 | }
44 |
45 | public void setCategory(String category) {
46 | this.category = category;
47 | }
48 |
49 | public String getIsbn() {
50 | return isbn;
51 | }
52 |
53 | public void setIsbn(String isbn) {
54 | this.isbn = isbn;
55 | }
56 |
57 | public String getDescription() {
58 | return description;
59 | }
60 |
61 | public void setDescription(String description) {
62 | this.description = description;
63 | }
64 |
65 | @Override
66 | public String toString() {
67 | return "Book{" +
68 | "name='" + name + '\'' +
69 | ", author='" + author + '\'' +
70 | ", year='" + year + '\'' +
71 | '}';
72 | }
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/pojos/User.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.pojos;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | public class User {
6 |
7 | @SerializedName("id")
8 | private String id;
9 |
10 | @SerializedName("full_name")
11 | private String fullName;
12 |
13 | @SerializedName("email")
14 | private String email;
15 |
16 | @SerializedName("password")
17 | private String password;
18 |
19 | @SerializedName("user_group_id")
20 | private String userGroupId;
21 |
22 | @SerializedName("image")
23 | private Object image;
24 |
25 | @SerializedName("extra_data")
26 | private Object extraData;
27 |
28 | @SerializedName("status")
29 | private String status;
30 |
31 | @SerializedName("is_admin")
32 | private String isAdmin;
33 |
34 | @SerializedName("start_date")
35 | private String startDate;
36 |
37 | @SerializedName("end_date")
38 | private String endDate;
39 |
40 | @SerializedName("address")
41 | private String address;
42 |
43 | /**
44 | * No args constructor for use in serialization
45 | *
46 | */
47 | public User() {
48 | }
49 |
50 | /**
51 | *
52 | * @param userGroupId
53 | * @param image
54 | * @param password
55 | * @param address
56 | * @param extraData
57 | * @param endDate
58 | * @param fullName
59 | * @param id
60 | * @param isAdmin
61 | * @param email
62 | * @param startDate
63 | * @param status
64 | */
65 | public User(String id, String fullName, String email, String password, String userGroupId, Object image, Object extraData, String status, String isAdmin, String startDate, String endDate, String address) {
66 | super();
67 | this.id = id;
68 | this.fullName = fullName;
69 | this.email = email;
70 | this.password = password;
71 | this.userGroupId = userGroupId;
72 | this.image = image;
73 | this.extraData = extraData;
74 | this.status = status;
75 | this.isAdmin = isAdmin;
76 | this.startDate = startDate;
77 | this.endDate = endDate;
78 | this.address = address;
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | return "User{" +
84 | "id='" + id + '\'' +
85 | ", fullName='" + fullName + '\'' +
86 | ", email='" + email + '\'' +
87 | ", password='" + password + '\'' +
88 | ", userGroupId='" + userGroupId + '\'' +
89 | ", image=" + image +
90 | ", extraData=" + extraData +
91 | ", status='" + status + '\'' +
92 | ", isAdmin='" + isAdmin + '\'' +
93 | ", startDate='" + startDate + '\'' +
94 | ", endDate='" + endDate + '\'' +
95 | ", address='" + address + '\'' +
96 | '}';
97 | }
98 |
99 | public String getId() {
100 | return id;
101 | }
102 |
103 | public void setId(String id) {
104 | this.id = id;
105 | }
106 |
107 | public String getFullName() {
108 | return fullName;
109 | }
110 |
111 | public void setFullName(String fullName) {
112 | this.fullName = fullName;
113 | }
114 |
115 | public String getEmail() {
116 | return email;
117 | }
118 |
119 | public void setEmail(String email) {
120 | this.email = email;
121 | }
122 |
123 | public String getPassword() {
124 | return password;
125 | }
126 |
127 | public void setPassword(String password) {
128 | this.password = password;
129 | }
130 |
131 | public String getUserGroupId() {
132 | return userGroupId;
133 | }
134 |
135 | public void setUserGroupId(String userGroupId) {
136 | this.userGroupId = userGroupId;
137 | }
138 |
139 | public Object getImage() {
140 | return image;
141 | }
142 |
143 | public void setImage(Object image) {
144 | this.image = image;
145 | }
146 |
147 | public Object getExtraData() {
148 | return extraData;
149 | }
150 |
151 | public void setExtraData(Object extraData) {
152 | this.extraData = extraData;
153 | }
154 |
155 | public String getStatus() {
156 | return status;
157 | }
158 |
159 | public void setStatus(String status) {
160 | this.status = status;
161 | }
162 |
163 | public String getIsAdmin() {
164 | return isAdmin;
165 | }
166 |
167 | public void setIsAdmin(String isAdmin) {
168 | this.isAdmin = isAdmin;
169 | }
170 |
171 | public String getStartDate() {
172 | return startDate;
173 | }
174 |
175 | public void setStartDate(String startDate) {
176 | this.startDate = startDate;
177 | }
178 |
179 | public String getEndDate() {
180 | return endDate;
181 | }
182 |
183 | public void setEndDate(String endDate) {
184 | this.endDate = endDate;
185 | }
186 |
187 | public String getAddress() {
188 | return address;
189 | }
190 |
191 | public void setAddress(String address) {
192 | this.address = address;
193 | }
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/runners/CukesRunner.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.runners;
2 |
3 | import io.cucumber.junit.Cucumber;
4 | import io.cucumber.junit.CucumberOptions;
5 | import org.junit.runner.RunWith;
6 |
7 | @RunWith(Cucumber.class)
8 | @CucumberOptions(
9 | plugin = {
10 | "pretty",
11 | "json:target/cucumber.json",
12 | "rerun:target/rerun.txt"
13 | },
14 |
15 | features = "src/test/resources/features",
16 | glue = "com/cybertek/library/step_definitions",
17 | dryRun = false
18 | // tags = "@lib-132"
19 | )
20 | public class CukesRunner {
21 | }
22 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/runners/FailedTestRunner.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.runners;
2 |
3 | import io.cucumber.junit.Cucumber;
4 | import io.cucumber.junit.CucumberOptions;
5 | import org.junit.runner.RunWith;
6 |
7 | @RunWith(Cucumber.class)
8 | @CucumberOptions(
9 | glue = "com/cybertek/library/step_definitions",
10 | features = "@target/rerun.txt"
11 | )
12 | public class FailedTestRunner {
13 |
14 | }
15 | // this does not report. to report add "html:target/default-cucumber-reports",
16 | // if you use the same report name as your runner file, it will
17 | // delete that report and create new one only ofr failed tests
18 | // if you write a differnet name, it wil create second report.
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/step_definitions/BaseStep.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.step_definitions;
2 |
3 | import com.cybertek.library.utilities.api.AuthenticationUtility;
4 | import com.cybertek.library.utilities.ui.Pages;
5 |
6 | import java.util.Map;
7 |
8 | public class BaseStep {
9 | protected AuthenticationUtility authenticationUtility;
10 | protected Pages pages = new Pages();
11 | protected static Map user;
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/test/java/com/cybertek/library/step_definitions/BooksStepDefs.java:
--------------------------------------------------------------------------------
1 | package com.cybertek.library.step_definitions;
2 |
3 | import com.cybertek.library.pages.BooksPage;
4 | import com.cybertek.library.pojos.Book;
5 | import com.cybertek.library.utilities.api.AuthenticationUtility;
6 | import com.cybertek.library.utilities.api.Endpoints;
7 | import com.cybertek.library.utilities.api.LibrarianAuthenticationUtility;
8 | import com.cybertek.library.utilities.db.DBUtils;
9 | import com.cybertek.library.utilities.ui.BrowserUtils;
10 | import io.cucumber.java.en.Then;
11 | import io.cucumber.java.en.When;
12 | import io.restassured.http.ContentType;
13 | import io.restassured.response.Response;
14 | import org.openqa.selenium.WebElement;
15 |
16 | import java.util.ArrayList;
17 | import java.util.List;
18 | import java.util.Map;
19 |
20 | import static io.restassured.RestAssured.given;
21 | import static org.hamcrest.MatcherAssert.assertThat;
22 | import static org.hamcrest.Matchers.is;
23 | import static org.junit.Assert.assertEquals;
24 |
25 | public class BooksStepDefs extends BaseStep {
26 | @Then("book information must match the api for {}")
27 | public void book_information_must_match_the_api_for_The_kite_runner(String book) {
28 | // call the database to get the book id for
29 | String query = "SELECT id FROM books WHERE name = '" + book + "'";
30 | String id = DBUtils.getCellValue(query).toString();
31 | // get the token
32 | AuthenticationUtility authenticationUtility = new LibrarianAuthenticationUtility();
33 | String token = authenticationUtility.getToken();
34 | // use the id to make the call to api
35 | Response response = given().
36 | log().all().
37 | header("x-library-token", token).
38 | pathParam("id", id).
39 | when().
40 | get(Endpoints.GET_BOOK_BY_ID).
41 | prettyPeek();
42 | // verify response vs ui
43 | response.then().statusCode(200).contentType(ContentType.JSON);
44 | Book bookPojo = response.as(Book.class);
45 |
46 | assertThat(bookPojo.getName(), is(pages.booksPage().bookName.getAttribute("value")));
47 | assertThat(bookPojo.getAuthor(), is(pages.booksPage().author.getAttribute("value")));
48 | assertThat(bookPojo.getIsbn(), is(pages.booksPage().isbn.getAttribute("value")));
49 | assertThat(bookPojo.getDescription(), is(pages.booksPage().description.getAttribute("value")));
50 |
51 | }
52 |
53 | @When("I open book {}")
54 | public void i_edit_book_The_kiterunner(String book) {
55 | System.out.println("book = " + book);
56 | BrowserUtils.waitForClickability(pages.booksPage().search, 5).sendKeys(book);
57 | BrowserUtils.waitForClickability(pages.booksPage().editBook(book), 5).click();
58 |
59 | }
60 |
61 | @Then("book information must match the database for {}")
62 | public void book_information_must_match_the_database_for_The_kite_runner(String book) {
63 |
64 | String sql = "SELECT b.isbn, b.year, b.author, bc.name, b.description\n" +
65 | "FROM books b\n" +
66 | "JOIN book_categories bc\n" +
67 | "ON b.book_category_id = bc.id\n" +
68 | "WHERE b.name = '" + book + "';";
69 | Map dbData = DBUtils.getRowMap(sql);
70 |
71 | DBUtils.getColumnNames(sql);
72 |
73 | assertEquals("author did not match", dbData.get("author").toString(), pages.booksPage().author.getAttribute("value"));
74 | assertEquals("year did not match", dbData.get("year").toString(), pages.booksPage().year.getAttribute("value"));
75 | assertEquals("isbn did not match", dbData.get("isbn").toString(), pages.booksPage().isbn.getAttribute("value"));
76 | assertEquals("description did not match", dbData.get("description").toString(), pages.booksPage().description.getAttribute("value"));
77 | assertEquals("category did not match", dbData.get("name").toString(), pages.booksPage().categoryList().getFirstSelectedOption().getText());
78 | }
79 | @Then("book categories must match book_categories table from db")
80 | public void book_categories_must_match_book_categories_table_from_db() {
81 | // get the expected categories from the database as a list
82 | String sql = "SELECT name FROM book_categories;";
83 | List