├── .gitignore
├── README.md
├── docker-compose.yml
├── logs
├── TestCase1_1.log
├── TestCase2_1.log
└── TestCase3_1.log
├── pom.xml
├── src
├── main
│ ├── java
│ │ ├── pageObjects
│ │ │ ├── HomePageObjects.java
│ │ │ ├── LoginPageObjects.java
│ │ │ ├── TaskPageObjects.java
│ │ │ └── UsersPageObjects.java
│ │ ├── reusableComponents
│ │ │ ├── ActionEngine.java
│ │ │ ├── DB_Operations.java
│ │ │ ├── ExcelOperations.java
│ │ │ ├── JiraOperations.java
│ │ │ ├── ListenersImplementation.java
│ │ │ ├── PropertiesOperations.java
│ │ │ ├── TestRetryAnalyzer.java
│ │ │ └── TestRetryAnalyzerListener.java
│ │ └── testBase
│ │ │ ├── BrowserFactory.java
│ │ │ ├── DriverFactory.java
│ │ │ ├── ExtentFactory.java
│ │ │ ├── ExtentReportNG.java
│ │ │ ├── MyLogger.java
│ │ │ └── TestBase.java
│ └── resources
│ │ └── log4j2.xml
└── test
│ ├── java
│ └── Tests
│ │ ├── TestCase.java
│ │ └── UserLoginTests.java
│ └── resources
│ ├── config.properties
│ └── testData
│ └── TaskCreationTestData.xlsx
└── testng.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | test-output/
4 | target/
5 | .settings
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Advanced Level - End to End Selenium Test Automation Framework (Testng - Java).
2 |
3 | For latest updates, do consider subscribe to my channel: https://www.youtube.com/automationtalks
4 |
5 | Before you go to this framework videos, You need to go through Basic Level Framework, Refer below Youtube Playlist for the same:
6 | Basic Level Selenium Framework: https://www.youtube.com/playlist?list=PL5fOKT7XR42Om0spD8QtxuQ4Y9ONra6dq
7 |
8 | Watch this space for more details on Advanced Level framework
9 |
10 | Refer below playlist (Under construction): https://www.youtube.com/playlist?list=PL5fOKT7XR42OgLXmX8wYYhB7L0sN-uqpR
11 |
12 | #Topic wise videos
13 |
14 | Video#1 - Course Introduction --> https://youtu.be/8OjTupvE8mI
15 |
16 | Video#2 - AUT and Test Cases walkthrough --> https://youtu.be/2cueo-051zI
17 |
18 | Video#3 - Create folder structure --> https://youtu.be/z-AKOHA1dnM
19 |
20 | Video#4 - Start creating Page Objects --> https://youtu.be/Thql1qrWFcI
21 |
22 | Video#5 - Demo on XPath writting tool - SelectorsHub --> https://youtu.be/QLCrVmy61Co
23 |
24 | Video#6 - Continued on Page Objects --> https://youtu.be/Jf-8Tte7bQE
25 |
26 | Video#7 - create browserfactory --> https://www.youtube.com/watch?v=pcVWuz8YEqQ
27 |
28 | Video#8 - create driverfactory --> https://www.youtube.com/watch?v=5wgusEV4uSQ
29 |
30 | Video#9 - Create Threadsafe TestBase --> https://youtu.be/diOPcwdGhmA
31 |
32 | video#10 - Create Threadsafe extent reporting --> https://youtu.be/N4JKX7qNw_s
33 |
34 | video#11 - Setup Extent Report via TestNG Listeners --> https://youtu.be/ro2mwk-YKvw
35 |
36 | video#12 - Setup Logging (Using Log4j2) - To Support Parallel Test Execution --> https://youtu.be/0JQekot_5V8
37 |
38 | Video#13 - Action Engine – Log every test action in Extent Report / Logger --> https://youtu.be/Tv2U0oa0OMY
39 |
40 | video#14 - Create Login Test – To verify Parallel Execution with Custom message logs --> https://youtu.be/6kuJUsS1haI
41 |
42 | video#15 - Create DataDriven Test for TaskCreation & Execute in Parallel - Part1 --> https://youtu.be/6CxQ6Pl6qS8
43 |
44 | video#16 - Database Validation in Selenium - Java Test Case (Threadsafe) --> https://youtu.be/7rgVF9x_HIk
45 |
46 | video#17 - Create DataDriven Test for TaskCreation & Execute in Parallel - Part2 --> https://youtu.be/Q6I90cyhlGM
47 |
48 | video#18 - Create Bug / Defect automatically in JIRA from Selenium Test Automation Framework (JIRA Rest API) -->
49 |
50 | video#19 - Add Attachment (Screenshot of failed Test Case) to Jira Issue (Via Jira Rest API) -->
51 |
52 | video#20 - Add Test Data in JIRA Automatic Defect / Bug Creation (Hashmap test data) -->
53 |
54 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # To execute this docker-compose yml file use `docker-compose -f docker-compose-v3.yml up`
2 | # Add the `-d` flag at the end for detached execution
3 | # To stop the execution, hit Ctrl+C, and then `docker-compose -f docker-compose-v3.yml down`version: "3"
4 | services:
5 | hub:
6 | image: selenium/hub
7 | ports:
8 | - "4444:4444"
9 | environment:
10 | GRID_MAX_SESSION: 16
11 | GRID_BROWSER_TIMEOUT: 3000
12 | GRID_TIMEOUT: 3000
13 |
14 | chrome:
15 | image: selenium/node-chrome
16 | depends_on:
17 | - hub
18 | environment:
19 | HUB_PORT_4444_TCP_ADDR: hub
20 | HUB_PORT_4444_TCP_PORT: 4444
21 | volumes:
22 | - /dev/shm:/dev/shm
23 | links:
24 | - hub
25 |
26 | firefox:
27 | image: selenium/node-firefox
28 | depends_on:
29 | - hub
30 | environment:
31 | HUB_PORT_4444_TCP_ADDR: hub
32 | HUB_PORT_4444_TCP_PORT: 4444
33 | volumes:
34 | - /dev/shm:/dev/shm
35 | links:
36 | - hub
--------------------------------------------------------------------------------
/logs/TestCase1_1.log:
--------------------------------------------------------------------------------
1 | [INFO ] 2020-09-13 14:25:52.235 - testBase.MyLogger:startTestCase 21==>
2 |
3 | ************** Execution Started : TestCase1**************
4 |
5 | [INFO ] 2020-09-13 14:25:52.276 - Tests.TestCase:TestCase1 23==> test 1 execution is in progress
6 |
--------------------------------------------------------------------------------
/logs/TestCase2_1.log:
--------------------------------------------------------------------------------
1 | [INFO ] 2020-09-13 14:25:52.219 - testBase.MyLogger:startTestCase 21==>
2 |
3 | ************** Execution Started : TestCase2**************
4 |
5 | [INFO ] 2020-09-13 14:25:52.234 - Tests.TestCase:TestCase2 31==> test2
6 |
--------------------------------------------------------------------------------
/logs/TestCase3_1.log:
--------------------------------------------------------------------------------
1 | [INFO ] 2020-09-13 14:25:52.088 - testBase.MyLogger:startTestCase 21==>
2 |
3 | ************** Execution Started : TestCase3**************
4 |
5 | [INFO ] 2020-09-13 14:25:52.218 - Tests.TestCase:TestCase3 40==> test3
6 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 | com.AutomationTalks
6 | AdavencedLevel.QDPM
7 | 0.0.1-SNAPSHOT
8 |
9 | UTF-8
10 | 1.8
11 | 1.8
12 |
13 |
14 |
15 |
16 |
17 | org.apache.maven.plugins
18 | maven-compiler-plugin
19 | 3.8.1
20 |
21 | 1.8
22 | 1.8
23 |
24 |
25 |
26 | org.apache.maven.plugins
27 | maven-surefire-plugin
28 | 3.0.0-M1
29 |
30 |
31 | ${project.basedir}\Output\${maven.build.timestamp}\Logs\
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 | testng.xml
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.seleniumhq.selenium
52 | selenium-java
53 | 3.141.59
54 |
55 |
56 | org.testng
57 | testng
58 | 7.1.0
59 |
60 |
61 | io.github.bonigarcia
62 | webdrivermanager
63 | 4.2.0
64 |
65 |
66 | com.aventstack
67 | extentreports
68 | 4.1.7
69 |
70 |
71 |
72 |
73 | org.apache.poi
74 | poi
75 | 4.1.2
76 |
77 |
78 |
79 | org.apache.poi
80 | poi-ooxml
81 | 4.1.2
82 |
83 |
84 | org.slf4j
85 | slf4j-simple
86 | 1.7.21
87 |
88 |
89 | org.apache.logging.log4j
90 | log4j-core
91 | 2.11.1
92 |
93 |
94 |
95 |
96 | mysql
97 | mysql-connector-java
98 | 8.0.21
99 |
100 |
101 |
103 |
104 | com.googlecode.json-simple
105 | json-simple
106 | 1.1
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/src/main/java/pageObjects/HomePageObjects.java:
--------------------------------------------------------------------------------
1 | package pageObjects;
2 |
3 | import org.openqa.selenium.By;
4 | import org.openqa.selenium.WebDriver;
5 | import org.openqa.selenium.WebElement;
6 | import org.openqa.selenium.support.FindBy;
7 | import org.openqa.selenium.support.PageFactory;
8 | import org.testng.Assert;
9 |
10 | import testBase.DriverFactory;
11 | import testBase.TestBase;
12 |
13 | public class HomePageObjects extends TestBase{
14 |
15 |
16 | By sidebarMenu_Dashboard = By.xpath("//ul[@class='page-sidebar-menu']//i/following-sibling::span[text()='Dashboard']");
17 |
18 | //click on menu bar - by passing name of menu
19 | public void clickOnSideMenu(String menu) {
20 | String MenuXpath = "//ul[@class='page-sidebar-menu']//i/following-sibling::span[text()='"+menu+"']";
21 | DriverFactory.getInstance().getDriver().findElement(By.xpath(MenuXpath)).click();
22 | }
23 |
24 | //click on sub menu bar - by passing name of menu
25 | public void clickOnSideSubMenu(String menu, String submenu) {
26 | String MenuXpath = "//ul[@class='page-sidebar-menu']//i/following-sibling::span[text()='"+menu+"']";
27 | DriverFactory.getInstance().getDriver().findElement(By.xpath(MenuXpath)).click();
28 | String submenuXpath="//ul[@class='page-sidebar-menu']//i/following-sibling::span[text()='"+menu+"']/ancestor::a/following-sibling::ul//span[text()='"+submenu+"']";
29 | DriverFactory.getInstance().getDriver().findElement(By.xpath(submenuXpath)).click();
30 | }
31 |
32 | public void checkIfDashBoardPageIsOpened() {
33 | Assert.assertTrue(isElementPresent_custom(DriverFactory.getInstance().getDriver().findElement(sidebarMenu_Dashboard), "DashBoardMenu"));
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/pageObjects/LoginPageObjects.java:
--------------------------------------------------------------------------------
1 | package pageObjects;
2 |
3 |
4 | import org.openqa.selenium.By;
5 |
6 | import testBase.DriverFactory;
7 | import testBase.TestBase;
8 |
9 | public class LoginPageObjects extends TestBase {
10 |
11 | By EMAIL = By.name("login[email]");
12 | By PASSWORD = By.name("login[password]");
13 | By LOGIN_BTN = By.xpath("//button[@type='submit' and text()='Login ']");
14 |
15 |
16 | //login to App
17 | public void login(String email, String password) {
18 | sendKeys_custom(DriverFactory.getInstance().getDriver().findElement(EMAIL), "LoginEmailFIeld", email);
19 | sendKeys_custom(DriverFactory.getInstance().getDriver().findElement(PASSWORD), "LoginPasswordFIeld", password);
20 |
21 | click_custom(DriverFactory.getInstance().getDriver().findElement(LOGIN_BTN), "LoginButton");
22 |
23 | }
24 |
25 |
26 | }
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/pageObjects/TaskPageObjects.java:
--------------------------------------------------------------------------------
1 | package pageObjects;
2 |
3 | import java.util.HashMap;
4 |
5 | import org.openqa.selenium.By;
6 |
7 | import testBase.DriverFactory;
8 | import testBase.TestBase;
9 |
10 | public class TaskPageObjects extends TestBase {
11 |
12 |
13 | By btn_addTask = By.xpath("//button[text()='Add Task']");
14 | By field_Search = By.id("search_menu");
15 | By txt_Search = By.xpath("//*[@id='search_menu']//input[@name='search[keywords]']");
16 | By btn_Search = By.xpath("//*[@id='search_menu']//input[@type='submit']");
17 | By dd_SelectProjectForNewTaskCreation = By.id("form_projects_id");
18 | By dd_taskType = By.id("tasks_tasks_type_id");
19 | By txt_taskName = By.id("tasks_name");
20 | By dd_taskStatus = By.id("tasks_tasks_status_id");
21 | By dd_taskPriority = By.id("tasks_tasks_priority_id");
22 | By dd_taskLabel = By.id("tasks_tasks_label_id");
23 | By dd_taskCreatedBy = By.id("tasks_created_by");
24 | By btn_save = By.xpath("//button[@type='submit' and text()='Save']");
25 |
26 |
27 | public void createTask(HashMap testData) throws Throwable {
28 | Thread.sleep(2000);
29 | selectDropDownByVisibleText_custom(DriverFactory.getInstance().getDriver().findElement(dd_SelectProjectForNewTaskCreation), "NewTaskProjectDropDown", testData.get("ProjectToCreateTaskUnder"));
30 | selectDropDownByVisibleText_custom(DriverFactory.getInstance().getDriver().findElement(dd_taskType), "NewTaskType", testData.get("TaskType"));
31 | sendKeys_custom(DriverFactory.getInstance().getDriver().findElement(txt_taskName), "newTaskName", testData.get("TaskName"));
32 | selectDropDownByVisibleText_custom(DriverFactory.getInstance().getDriver().findElement(dd_taskStatus), "NewTaskStatus", testData.get("TaskStatus"));
33 | selectDropDownByVisibleText_custom(DriverFactory.getInstance().getDriver().findElement(dd_taskPriority), "NewTaskPriority", testData.get("TaskPriority"));
34 | selectDropDownByVisibleText_custom(DriverFactory.getInstance().getDriver().findElement(dd_taskLabel), "NewTaskLabel", testData.get("Label"));
35 | click_custom(DriverFactory.getInstance().getDriver().findElement(btn_save), "NewTaskSaveButton");
36 |
37 | }
38 |
39 | public void Search_Verify_TaskCreationOnUI(HashMap testData) throws Throwable {
40 |
41 | moveToElement_custom(DriverFactory.getInstance().getDriver().findElement(field_Search), "TaskSearchOption");
42 | sendKeys_custom(DriverFactory.getInstance().getDriver().findElement(txt_Search), "TaskSearchBox", testData.get("TaskName"));
43 | click_custom(DriverFactory.getInstance().getDriver().findElement(btn_Search), "SearchButton");
44 |
45 | //table verification
46 | assertEqualsString_custom(testData.get("TaskName"), getTaskTableCellValueByColumnName("Name"), "TaskNameInTable");
47 |
48 | }
49 |
50 | private String getTaskTableCellValueByColumnName(String columnName) {
51 |
52 | String valueXpath = "//table[starts-with(@id, 'itmes_listing')]/tbody/tr/td[count(//table[starts-with(@id, 'itmes_listing')]/thead/tr/th/div[text()='"+columnName+"']/parent::th/preceding-sibling::th)+1]";
53 | String value = DriverFactory.getInstance().getDriver().findElement(By.xpath(valueXpath)).getText();
54 | return value;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/pageObjects/UsersPageObjects.java:
--------------------------------------------------------------------------------
1 | package pageObjects;
2 |
3 | import org.openqa.selenium.By;
4 |
5 | public class UsersPageObjects {
6 |
7 | By btn_addUser = By.xpath("//button[text()='Add User']");
8 | By field_Search = By.id("search_menu");
9 | By txt_Search = By.xpath("//*[@id='search_menu']//input[@name='search[keywords]']");
10 | By btn_Search = By.xpath("//*[@id='search_menu']//input[@type='submit']");
11 | By dd_group = By.id("users_users_group_id");
12 | By txt_FullName = By.name("users[name]");
13 | By txt_Password = By.name("users[password]");
14 | By txt_Email = By.name("users[email]");
15 | By txt_Phone = By.name("extra_fields[9]");
16 | By btn_UserPhoto = By.id("users_photo");
17 | By btn_Save = By.id("submit_button");
18 | By chk_notifyUser = By.id("users_notify");
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/reusableComponents/ActionEngine.java:
--------------------------------------------------------------------------------
1 | package reusableComponents;
2 |
3 | import org.openqa.selenium.JavascriptExecutor;
4 | import org.openqa.selenium.WebElement;
5 | import org.openqa.selenium.interactions.Actions;
6 | import org.openqa.selenium.support.ui.Select;
7 | import org.testng.Assert;
8 |
9 | import com.aventstack.extentreports.Status;
10 |
11 | import testBase.DriverFactory;
12 | import testBase.ExtentFactory;
13 |
14 | /**
15 | * @author: Prakash Narkhede
16 | * @Youtube: https://www.youtube.com/automationtalks
17 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
18 | */
19 | public class ActionEngine {
20 |
21 | //Customized sendkeys method-> To log sendkeys message for every occ.
22 | public void sendKeys_custom(WebElement element, String fieldName, String valueToBeSent) {
23 | try {
24 | element.sendKeys(valueToBeSent);
25 | //log success message in exgent report
26 | ExtentFactory.getInstance().getExtent().log(Status.PASS, fieldName+"==> Ented value as: "+valueToBeSent);
27 | } catch (Exception e) {
28 | //log failure in extent
29 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "Value enter in field: "+fieldName + " is failed due to exception: "+e);
30 | }
31 | }
32 |
33 |
34 | //custom click method to log evey click action in to extent report
35 | public void click_custom(WebElement element, String fieldName) {
36 | try {
37 | element.click();
38 | //log success message in exgent report
39 | ExtentFactory.getInstance().getExtent().log(Status.PASS, fieldName+"==> Clicked Successfully! ");
40 | } catch (Exception e) {
41 | //log failure in extent
42 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "Unable to click on field: " +fieldName +" due to exception: "+e);
43 | }
44 | }
45 |
46 |
47 | //clear data from field
48 | public void clear_custom(WebElement element,String fieldName) {
49 | try {
50 | element.clear();
51 | Thread.sleep(250);
52 | ExtentFactory.getInstance().getExtent().log(Status.PASS, fieldName+"==> Data Cleared Successfully! ");
53 | } catch (Exception e) {
54 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "Unable to clear Data on field: " +fieldName +" due to exception: "+e);
55 |
56 | }
57 | }
58 |
59 | //custom mouseHover
60 | public void moveToElement_custom(WebElement element,String fieldName){
61 | try{
62 | JavascriptExecutor executor = (JavascriptExecutor) DriverFactory.getInstance().getDriver();
63 | executor.executeScript("arguments[0].scrollIntoView(true);", element);
64 | Actions actions = new Actions(DriverFactory.getInstance().getDriver());
65 | actions.moveToElement(element).build().perform();
66 | ExtentFactory.getInstance().getExtent().log(Status.PASS, fieldName+"==> Mouse hovered Successfully! ");
67 | Thread.sleep(1000);
68 | }catch(Exception e){
69 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "Unable to hover mouse on field: " +fieldName +" due to exception: "+e);
70 |
71 | }
72 | }
73 |
74 |
75 | //check if element is Present
76 | public boolean isElementPresent_custom(WebElement element,String fieldName){
77 | boolean flag = false;
78 | try {
79 | flag = element.isDisplayed();
80 | ExtentFactory.getInstance().getExtent().log(Status.PASS, fieldName+"==> Presence of field is: "+ flag);
81 | return flag;
82 | } catch (Exception e) {
83 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "Checking for presence of field: " +fieldName +" not tested due to exception: "+e);
84 | return flag;
85 | }
86 | }
87 |
88 |
89 | //Select dropdown value value by visibleText
90 | public void selectDropDownByVisibleText_custom(WebElement element, String fieldName, String ddVisibleText) throws Throwable {
91 | try {
92 | Select s = new Select(element);
93 | s.selectByVisibleText(ddVisibleText);
94 | ExtentFactory.getInstance().getExtent().log(Status.PASS, fieldName+"==> Dropdown Value Selected by visible text: "+ ddVisibleText);
95 | } catch (Exception e) {
96 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "Dropdown value not selected for field: " +fieldName +" due to exception: "+e);
97 | }
98 | }
99 |
100 | //Select dropdown value value by value
101 | public void selectDropDownByValue_custom(WebElement element, String fieldName, String ddValue) throws Throwable {
102 | try {
103 | Select s = new Select(element);
104 | s.selectByValue(ddValue);
105 | ExtentFactory.getInstance().getExtent().log(Status.PASS, fieldName+"==> Dropdown Value Selected by visible text: "+ ddValue);
106 | } catch (Exception e) {
107 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "Dropdown value not selected for field: " +fieldName +" due to exception: "+e);
108 | }
109 | }
110 |
111 | //String Asserts
112 | public void assertEqualsString_custom(String expvalue, String actualValue, String locatorName) throws Throwable {
113 | try {
114 | if(actualValue.equals(expvalue)) {
115 | ExtentFactory.getInstance().getExtent().log(Status.PASS, "String Assertion is successful on field "+ locatorName + " Expected value was: "+ expvalue + " actual value is: "+actualValue);
116 | }else {
117 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "String Assertion FAILED on field "+ locatorName + " Expected value was: "+ expvalue + " actual value is: "+actualValue);
118 | Assert.assertTrue(false);
119 | }
120 | } catch (Exception e) {
121 | Assert.assertTrue(false, e.toString());
122 | }
123 | }
124 |
125 | //Get text from webelement
126 | public String getText_custom(WebElement element, String fieldName) {
127 | String text = "";
128 | try {
129 | text = element.getText();
130 | ExtentFactory.getInstance().getExtent().log(Status.PASS, fieldName+"==> Text retried is: "+ text);
131 | return text;
132 | } catch (Exception e) {
133 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, fieldName+"==> Text not retried due to exception: "+ e);
134 |
135 | }
136 | return text;
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/src/main/java/reusableComponents/DB_Operations.java:
--------------------------------------------------------------------------------
1 | package reusableComponents;
2 |
3 | import java.sql.*;
4 | import java.util.HashMap;
5 | /**
6 | * @author: Prakash Narkhede
7 | * @Youtube: https://www.youtube.com/automationtalks
8 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
9 | */
10 | public class DB_Operations {
11 |
12 | public synchronized HashMap getSqlResultInMap(String sql) {
13 | HashMap data_map = new HashMap<>();
14 |
15 | try{
16 | Class.forName("com.mysql.cj.jdbc.Driver");
17 | Connection con=DriverManager.getConnection(
18 | "jdbc:mysql://localhost:3306/qdpm_qa?serverTimezone=UTC","root","");
19 |
20 | Statement stmt=con.createStatement();
21 | ResultSet rs=stmt.executeQuery(sql);
22 | ResultSetMetaData md = rs.getMetaData();
23 |
24 | while (rs.next()) {
25 | for (int i = 1; i <= md.getColumnCount(); i++) {
26 | data_map.put(md.getColumnName(i), rs.getString(i));
27 | }
28 | }
29 | System.out.println(data_map);
30 | con.close();
31 | }catch(Exception e){ System.out.println(e);}
32 | return data_map;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/reusableComponents/ExcelOperations.java:
--------------------------------------------------------------------------------
1 | package reusableComponents;
2 |
3 | import java.io.File;
4 | import java.util.HashMap;
5 |
6 | import org.apache.poi.ss.usermodel.CellType;
7 | import org.apache.poi.ss.usermodel.Sheet;
8 | import org.apache.poi.ss.usermodel.Workbook;
9 | import org.apache.poi.ss.usermodel.WorkbookFactory;
10 |
11 | public class ExcelOperations {
12 |
13 | String filePath;
14 | Sheet sh;
15 |
16 | public ExcelOperations(String sheetName) {
17 | try {
18 | filePath = System.getProperty("user.dir")+PropertiesOperations.getPropertyValueByKey("testDataLocation");
19 | } catch (Exception e) {
20 | e.printStackTrace();
21 | }
22 | //open file - workbook
23 | File testDataFile = new File(filePath);
24 | Workbook wb = null;
25 | try {
26 | wb = WorkbookFactory.create(testDataFile);
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | }
30 |
31 | sh = wb.getSheet(sheetName);
32 | }
33 |
34 | //get test data from test data sheet in hashmap based on row number
35 | @SuppressWarnings("deprecation")
36 | public HashMap getTestDataInMap(int rowNum) throws Exception {
37 | //read data row by row and put in map
38 | HashMap hm = new HashMap();
39 |
40 | for (int i = 0; i < sh.getRow(0).getLastCellNum(); i++) {
41 | String value;
42 | if(sh.getRow(rowNum).getCell(i) != null) {
43 | sh.getRow(rowNum).getCell(i).setCellType(CellType.STRING);
44 | value = sh.getRow(rowNum).getCell(i).toString();
45 | }
46 | else {
47 | value = "";
48 | }
49 | hm.put(sh.getRow(0).getCell(i).toString(), value);
50 | }
51 | return hm;
52 | }
53 |
54 | //get row count
55 | public int getRowCount() {
56 | return sh.getLastRowNum();
57 | }
58 |
59 | //ger column count
60 | public int getColCount() {
61 | return sh.getRow(0).getLastCellNum();
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/reusableComponents/JiraOperations.java:
--------------------------------------------------------------------------------
1 | package reusableComponents;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.util.Base64;
6 |
7 | import org.apache.http.HttpResponse;
8 | import org.apache.http.client.ClientProtocolException;
9 | import org.apache.http.client.HttpClient;
10 | import org.apache.http.client.methods.HttpPost;
11 | import org.apache.http.entity.StringEntity;
12 | import org.apache.http.entity.mime.MultipartEntityBuilder;
13 | import org.apache.http.entity.mime.content.FileBody;
14 | import org.apache.http.impl.client.HttpClientBuilder;
15 | import org.apache.http.util.EntityUtils;
16 | import org.json.simple.JSONObject;
17 | import org.json.simple.parser.JSONParser;
18 | import org.json.simple.parser.ParseException;
19 |
20 | /**
21 | * @author: Prakash Narkhede
22 | * @Youtube: https://www.youtube.com/automationtalks
23 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
24 | */
25 | public class JiraOperations {
26 | String jiraURL = PropertiesOperations.getPropertyValueByKey("jiraURL");
27 | String jiraUserName = PropertiesOperations.getPropertyValueByKey("jiraUserName");
28 | String jiraAccessKey = PropertiesOperations.getPropertyValueByKey("jiraSecretKey");
29 |
30 |
31 | //create Jira Issue as bug
32 | public String createJiraIssue(String ProjectName, String issueSummary, String issueDescription, String component, String priority, String label, String env, String assignee) throws ClientProtocolException, IOException, ParseException {
33 |
34 | String issueId = null; //to store issue / bug id.
35 |
36 | HttpClient httpClient = HttpClientBuilder.create().build();
37 | String url = jiraURL+"/rest/api/3/issue";
38 | HttpPost postRequest = new HttpPost(url);
39 | postRequest.addHeader("content-type", "application/json");
40 |
41 | // BASE64Encoder base=new BASE64Encoder();
42 | String encoding = Base64.getEncoder().encodeToString((jiraUserName+":"+jiraAccessKey).getBytes());
43 | //String encoding = base.encode((jiraUserName+":"+jiraAccessKey).getBytes());
44 | postRequest.setHeader("Authorization", "Basic " + encoding);
45 |
46 | StringEntity params = new StringEntity(createPayloadForCreateJiraIssue(ProjectName, issueSummary, issueDescription, component, priority, label, env, assignee));
47 | postRequest.setEntity(params);
48 | HttpResponse response = httpClient.execute(postRequest);
49 |
50 | //convert httpresponse to string
51 | String jsonString = EntityUtils.toString(response.getEntity());
52 |
53 | //convert sring to Json
54 | JSONParser parser = new JSONParser();
55 | JSONObject json = (JSONObject) parser.parse(jsonString);
56 |
57 | //extract issuekey from Json
58 | issueId = (String) json.get("key");
59 |
60 | return issueId;
61 |
62 | }
63 |
64 | //Add attachment to already created bug / issue in JIRA
65 | public void addAttachmentToJiraIssue(String issueId, String filePath) throws ClientProtocolException, IOException
66 | {
67 | String pathname= filePath;
68 | File fileUpload = new File(pathname);
69 |
70 | HttpClient httpClient = HttpClientBuilder.create().build();
71 | String url = jiraURL+"/rest/api/3/issue/"+issueId+"/attachments";
72 | HttpPost postRequest = new HttpPost(url);
73 |
74 | //BASE64Encoder base=new BASE64Encoder();
75 | //String encoding = base.encode((jiraUserName+":"+jiraAccessKey).getBytes());
76 | String encoding = Base64.getEncoder().encodeToString((jiraUserName+":"+jiraAccessKey).getBytes());
77 |
78 | postRequest.setHeader("Authorization", "Basic " + encoding);
79 | postRequest.setHeader("X-Atlassian-Token","nocheck");
80 |
81 | MultipartEntityBuilder entity=MultipartEntityBuilder.create();
82 | entity.addPart("file", new FileBody(fileUpload));
83 | postRequest.setEntity( entity.build());
84 | HttpResponse response = httpClient.execute(postRequest);
85 | System.out.println(response.getStatusLine());
86 |
87 | if(response.getStatusLine().toString().contains("200 OK")){
88 | System.out.println("Attachment uploaded");
89 | } else{
90 | System.out.println("Attachment not uploaded");
91 | }
92 | }
93 |
94 | //creates payload for create issue post request
95 | private static String createPayloadForCreateJiraIssue(String ProjectName, String issueSummary, String issueDescription, String componentId, String priority, String label, String env, String assigneeId) {
96 | return "{\r\n" +
97 | " \"fields\": {\r\n" +
98 | " \"project\":\r\n" +
99 | " {\r\n" +
100 | " \"key\": \""+ProjectName+"\"\r\n" +
101 | " },\r\n" +
102 | " \"summary\": \""+issueSummary+"\",\r\n" +
103 | " \"description\": {\r\n" +
104 | " \"type\": \"doc\",\r\n" +
105 | " \"version\": 1,\r\n" +
106 | " \"content\": [\r\n" +
107 | " {\r\n" +
108 | " \"type\": \"paragraph\",\r\n" +
109 | " \"content\": [\r\n" +
110 | " {\r\n" +
111 | " \"text\": \""+issueDescription+"\",\r\n" +
112 | " \"type\": \"text\"\r\n" +
113 | " }\r\n" +
114 | " ]\r\n" +
115 | " }\r\n" +
116 | " ]\r\n" +
117 | " }, \r\n" +
118 | " \"issuetype\": {\r\n" +
119 | " \"name\": \"Bug\"\r\n" +
120 | " },\r\n" +
121 | " \"components\": [\r\n" +
122 | " {\r\n" +
123 | " \"id\": \""+componentId+"\"\r\n" +
124 | " }\r\n" +
125 | " ],\r\n" +
126 | " \"priority\": {\r\n" +
127 | " \"id\": \""+priority+"\"\r\n" +
128 | " },\r\n" +
129 | " \"labels\": [\r\n" +
130 | " \""+label+"\"\r\n" +
131 | " ],\r\n" +
132 | " \"environment\": {\r\n" +
133 | " \"type\": \"doc\",\r\n" +
134 | " \"version\": 1,\r\n" +
135 | " \"content\": [\r\n" +
136 | " {\r\n" +
137 | " \"type\": \"paragraph\",\r\n" +
138 | " \"content\": [\r\n" +
139 | " {\r\n" +
140 | " \"text\": \""+env+"\",\r\n" +
141 | " \"type\": \"text\"\r\n" +
142 | " }\r\n" +
143 | " ]\r\n" +
144 | " }\r\n" +
145 | " ]\r\n" +
146 | " },\r\n" +
147 | " \"assignee\": {\r\n" +
148 | " \"id\": \""+assigneeId+"\"\r\n" +
149 | " }\r\n" +
150 | "}\r\n" +
151 | "}";
152 | }
153 |
154 |
155 | }
156 |
157 |
--------------------------------------------------------------------------------
/src/main/java/reusableComponents/ListenersImplementation.java:
--------------------------------------------------------------------------------
1 | package reusableComponents;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.text.SimpleDateFormat;
6 | import java.util.Date;
7 |
8 | import org.apache.commons.io.FileUtils;
9 | import org.apache.http.client.ClientProtocolException;
10 | import org.json.simple.parser.ParseException;
11 | import org.openqa.selenium.OutputType;
12 | import org.openqa.selenium.TakesScreenshot;
13 | import org.testng.ITestContext;
14 | import org.testng.ITestListener;
15 | import org.testng.ITestResult;
16 |
17 | import com.aventstack.extentreports.ExtentReports;
18 | import com.aventstack.extentreports.ExtentTest;
19 | import com.aventstack.extentreports.Status;
20 |
21 | import testBase.DriverFactory;
22 | import testBase.ExtentFactory;
23 | import testBase.ExtentReportNG;
24 |
25 | /**
26 | * @author: Prakash Narkhede
27 | * @Youtube: https://www.youtube.com/automationtalks
28 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
29 | */
30 | public class ListenersImplementation implements ITestListener{
31 | JiraOperations jiraOps = new JiraOperations();
32 | static ExtentReports report;
33 | ExtentTest test;
34 |
35 | public void onTestStart(ITestResult result) {
36 | //before each test case
37 | test = report.createTest(result.getMethod().getMethodName());
38 | ExtentFactory.getInstance().setExtent(test);
39 | }
40 |
41 | public void onTestSuccess(ITestResult result) {
42 | ExtentFactory.getInstance().getExtent().log(Status.PASS, "Test Case: "+result.getMethod().getMethodName()+ " is Passed.");
43 | ExtentFactory.getInstance().removeExtentObject();
44 | }
45 |
46 | public void onTestFailure(ITestResult result) {
47 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, "Test Case: "+result.getMethod().getMethodName()+ " is Failed.");
48 | ExtentFactory.getInstance().getExtent().log(Status.FAIL, result.getThrowable());
49 |
50 | //add screenshot for failed test.
51 | File src = ((TakesScreenshot)DriverFactory.getInstance().getDriver()).getScreenshotAs(OutputType.FILE);
52 | SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyy HH-mm-ss");
53 | Date date = new Date();
54 | String actualDate = format.format(date);
55 |
56 | String screenshotPath = System.getProperty("user.dir")+
57 | "/Reports/Screenshots/"+actualDate+".jpeg";
58 | File dest = new File(screenshotPath);
59 |
60 | try {
61 | FileUtils.copyFile(src, dest);
62 | } catch (IOException e) {
63 | e.printStackTrace();
64 | }
65 | try {
66 | ExtentFactory.getInstance().getExtent().addScreenCaptureFromPath(screenshotPath, "Test case failure screenshot");
67 | ExtentFactory.getInstance().removeExtentObject();
68 |
69 | } catch (IOException e) {
70 | e.printStackTrace();
71 | }
72 | ///////JIRA defect creation part
73 | String automaticJIRAcreation = PropertiesOperations.getPropertyValueByKey("automatic_Issue_Creation_In_JIRA");
74 | if(automaticJIRAcreation.trim().equalsIgnoreCase("ON")) {
75 | String issueS = "Automation Test Failed - "+result.getMethod().getMethodName();
76 | String issueD = "Test Data to be passed here.";
77 | String issueNumber = null;
78 | try {
79 | issueNumber = jiraOps.createJiraIssue("QDPM", issueS, issueD, "10000", "5", "QDPM", "SIT", "5f782c4b95fe8e0069705791");
80 | } catch (Exception e1) {
81 | e1.printStackTrace();
82 | }
83 | try {
84 | jiraOps.addAttachmentToJiraIssue(issueNumber, screenshotPath);
85 | } catch (Exception e) {
86 | e.printStackTrace();
87 | }
88 | }
89 |
90 | }
91 |
92 | public void onTestSkipped(ITestResult result) {
93 | ExtentFactory.getInstance().getExtent().log(Status.SKIP, "Test Case: "+result.getMethod().getMethodName()+ " is skipped.");
94 | ExtentFactory.getInstance().removeExtentObject();
95 | }
96 |
97 | public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
98 | }
99 |
100 | public void onTestFailedWithTimeout(ITestResult result) {
101 | }
102 |
103 | public void onStart(ITestContext context) {
104 | try {
105 | report = ExtentReportNG.setupExtentReport();
106 | } catch (Exception e) {
107 | e.printStackTrace();
108 | }
109 | }
110 |
111 | public void onFinish(ITestContext context) {
112 | //close extent
113 | report.flush();
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/reusableComponents/PropertiesOperations.java:
--------------------------------------------------------------------------------
1 | package reusableComponents;
2 |
3 | /**
4 | * @author: Prakash Narkhede
5 | * @Youtube: https://www.youtube.com/automationtalks
6 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
7 | */
8 |
9 | import java.io.FileInputStream;
10 | import java.util.Properties;
11 |
12 | import org.apache.commons.lang3.StringUtils;
13 |
14 | public class PropertiesOperations {
15 |
16 |
17 | static Properties prop = new Properties();
18 |
19 | public static String getPropertyValueByKey(String key) {
20 | //1. load data from properties file
21 | String propFilePath = System.getProperty("user.dir")+"/src/test/resources/config.properties";
22 | FileInputStream fis;
23 | try {
24 | fis = new FileInputStream(propFilePath);
25 | prop.load(fis);
26 | } catch (Exception e) {
27 | e.printStackTrace();
28 | }
29 |
30 | //2. read data
31 | String value = prop.get(key).toString();
32 |
33 | if(StringUtils.isEmpty(value)) {
34 | try {
35 | throw new Exception("Value is not specified for key: "+key + " in properties file.");
36 | }catch(Exception e) {}
37 | }
38 |
39 | return value;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/reusableComponents/TestRetryAnalyzer.java:
--------------------------------------------------------------------------------
1 | package reusableComponents;
2 |
3 | import org.testng.IRetryAnalyzer;
4 | import org.testng.ITestResult;
5 |
6 | /**
7 | * @author: Prakash Narkhede
8 | * @Youtube: https://www.youtube.com/automationtalks
9 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
10 | */
11 | public class TestRetryAnalyzer implements IRetryAnalyzer {
12 |
13 | int counter = 1;
14 | int retryMaxLimit = Integer.valueOf(PropertiesOperations.getPropertyValueByKey("retryCount"));
15 |
16 | @Override
17 | public boolean retry(ITestResult result) {
18 | if(counter define separate factory methods for creating objects and create objects by calling that methods
26 | ThreadLocal driver = new ThreadLocal();
27 |
28 | public WebDriver getDriver() {
29 | return driver.get();
30 | }
31 |
32 | public void setDriver(WebDriver driverParm) {
33 | driver.set(driverParm);
34 | }
35 |
36 |
37 | public void closeBrowser() {
38 | driver.get().quit();
39 | driver.remove();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/testBase/ExtentFactory.java:
--------------------------------------------------------------------------------
1 | package testBase;
2 |
3 | import com.aventstack.extentreports.ExtentTest;
4 |
5 | /**
6 | * @author: Prakash Narkhede
7 | * @Youtube: https://www.youtube.com/automationtalks
8 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
9 | */
10 | public class ExtentFactory {
11 | //Singleton design Pattern
12 | //private constructor so that no one else can create object of this class
13 | private ExtentFactory() {
14 |
15 | }
16 |
17 | private static ExtentFactory instance = new ExtentFactory();
18 |
19 | public static ExtentFactory getInstance() {
20 | return instance;
21 | }
22 |
23 |
24 | //factory design pattern --> define separate factory methods for creating objects and create objects by calling that methods
25 | ThreadLocal extent = new ThreadLocal();
26 |
27 | public ExtentTest getExtent() {
28 | return extent.get();
29 | }
30 |
31 | public void setExtent(ExtentTest extentTestObject) {
32 | extent.set(extentTestObject);
33 | }
34 |
35 | public void removeExtentObject() {
36 | extent.remove();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/testBase/ExtentReportNG.java:
--------------------------------------------------------------------------------
1 | package testBase;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Date;
5 |
6 | import com.aventstack.extentreports.ExtentReports;
7 | import com.aventstack.extentreports.reporter.ExtentSparkReporter;
8 | import com.aventstack.extentreports.reporter.configuration.Theme;
9 |
10 | import reusableComponents.PropertiesOperations;
11 |
12 | /**
13 | * @author: Prakash Narkhede
14 | * @Youtube: https://www.youtube.com/automationtalks
15 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
16 | */
17 | public class ExtentReportNG {
18 |
19 | static ExtentReports extent;
20 |
21 | public static ExtentReports setupExtentReport() throws Exception {
22 | SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyy HH-mm-ss");
23 | Date date = new Date();
24 | String actualDate = format.format(date);
25 |
26 | String reportPath = System.getProperty("user.dir")+
27 | "/Reports/ExecutionReport_"+actualDate+".html";
28 |
29 | ExtentSparkReporter sparkReport = new ExtentSparkReporter(reportPath);
30 |
31 | extent = new ExtentReports();
32 | extent.attachReporter(sparkReport);
33 |
34 | sparkReport.config().setDocumentTitle("DocumentTitle");
35 | sparkReport.config().setTheme(Theme.DARK);
36 | sparkReport.config().setReportName("ReportName");
37 |
38 | extent.setSystemInfo("Executed on Environment: ", PropertiesOperations.getPropertyValueByKey("url"));
39 | extent.setSystemInfo("Executed on Browser: ", PropertiesOperations.getPropertyValueByKey("browser"));
40 | extent.setSystemInfo("Executed on OS: ", System.getProperty("os.name"));
41 | extent.setSystemInfo("Executed by User: ", System.getProperty("user.name"));
42 |
43 | return extent;
44 | }
45 |
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/testBase/MyLogger.java:
--------------------------------------------------------------------------------
1 | package testBase;
2 |
3 | import java.io.File;
4 |
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.apache.logging.log4j.ThreadContext;
8 |
9 | /**
10 | * @author: Prakash Narkhede
11 | * @Youtube: https://www.youtube.com/automationtalks
12 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
13 | */
14 | public class MyLogger {
15 |
16 | private static Logger logger = LogManager.getLogger();
17 |
18 | public static synchronized void startTestCase(String sTestCaseName) {
19 | sTestCaseName = sTestCaseName.replaceAll("[^a-zA-Z0-9]", "_").replaceAll("_+", "_");
20 | startLog(System.getProperty("user.dir"), sTestCaseName);
21 | info("\n\n************** Execution Started : " + sTestCaseName + "**************\n");
22 | }
23 |
24 | public static void endTestCase(String sTestCaseName) {
25 | info("\n\n************** Execution End : " + sTestCaseName + "**************\n");
26 | }
27 |
28 | private static void startLog(String dirPath, String testCaseName) {
29 |
30 | int noOfFiles = 0;
31 |
32 | File dir = new File(dirPath);
33 | if (dir.exists()) {
34 | int count = 0;
35 | for (File file : dir.listFiles()) {
36 | if (file.isFile() && file.getName().endsWith(".log") && file.getName().contains(testCaseName)) {
37 | count++;
38 | }
39 | }
40 | noOfFiles = count;
41 | }
42 |
43 | noOfFiles++;
44 | String logFileName = testCaseName + "_" + noOfFiles;
45 |
46 | ThreadContext.put("logFilename", logFileName);
47 | }
48 |
49 | public static Logger getCurrentLog() {
50 | return logger;
51 | }
52 |
53 | public static String getCallInfo() {
54 |
55 | String callInfo;
56 | String className = Thread.currentThread().getStackTrace()[3].getClassName();
57 | String methodName = Thread.currentThread().getStackTrace()[3].getMethodName();
58 | int lineNumber = Thread.currentThread().getStackTrace()[3].getLineNumber();
59 |
60 | callInfo = className + ":" + methodName + " " + lineNumber+ "==> ";
61 | return callInfo;
62 |
63 | }
64 |
65 | public static void trace(Object message) {
66 | getCurrentLog().trace(message);
67 | }
68 |
69 | public static void trace(Object message, Throwable t) {
70 | getCurrentLog().trace(message, t);
71 | }
72 |
73 | public static void debug(Object message) {
74 |
75 | getCurrentLog().debug(getCallInfo() + message);
76 | }
77 |
78 | public static void debug(Object message, Throwable t) {
79 | getCurrentLog().debug(getCallInfo() + message, t);
80 | }
81 |
82 | public static void error(Object message) {
83 |
84 | getCurrentLog().error(getCallInfo() + message);
85 | }
86 |
87 | public static void error(Object message, Throwable t) {
88 | getCurrentLog().error(getCallInfo() + message, t);
89 | }
90 |
91 | public static void fatal(Object message) {
92 | getCurrentLog().fatal(getCallInfo() + message);
93 | }
94 |
95 | public static void fatal(Object message, Throwable t) {
96 | getCurrentLog().fatal(getCallInfo() + message, t);
97 | }
98 |
99 | public static void info(Object message) {
100 |
101 | getCurrentLog().info(getCallInfo() + message);
102 | }
103 |
104 | public static void info(Object message, Throwable t) {
105 | getCurrentLog().info(getCallInfo() + message, t);
106 | }
107 |
108 | public static void warn(Object message) {
109 | getCurrentLog().warn(getCallInfo() + message);
110 | }
111 |
112 | public static void warn(Object message, Throwable t) {
113 | getCurrentLog().warn(getCallInfo() + message, t);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/main/java/testBase/TestBase.java:
--------------------------------------------------------------------------------
1 | package testBase;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import org.testng.annotations.AfterMethod;
6 | import org.testng.annotations.BeforeMethod;
7 |
8 | import reusableComponents.ActionEngine;
9 | import reusableComponents.PropertiesOperations;
10 |
11 | /**
12 | * @author: Prakash Narkhede
13 | * @Youtube: https://www.youtube.com/automationtalks
14 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
15 | */
16 | public class TestBase extends ActionEngine {
17 | BrowserFactory bf = new BrowserFactory();
18 |
19 | @BeforeMethod
20 | public void LaunchApplication() throws Exception {
21 | String browser = PropertiesOperations.getPropertyValueByKey("browser");
22 | String url = PropertiesOperations.getPropertyValueByKey("url");
23 |
24 | DriverFactory.getInstance().setDriver(bf.createBrowserInstance(browser));
25 |
26 | DriverFactory.getInstance().getDriver().manage().window().maximize();
27 | DriverFactory.getInstance().getDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
28 | DriverFactory.getInstance().getDriver().navigate().to(url);
29 |
30 | }
31 |
32 | @AfterMethod
33 | public void tearDown() {
34 | DriverFactory.getInstance().closeBrowser();
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/test/java/Tests/TestCase.java:
--------------------------------------------------------------------------------
1 | package Tests;
2 |
3 | import java.util.HashMap;
4 |
5 | import org.testng.annotations.DataProvider;
6 | import org.testng.annotations.Test;
7 | import pageObjects.HomePageObjects;
8 | import pageObjects.LoginPageObjects;
9 | import pageObjects.TaskPageObjects;
10 | import reusableComponents.DB_Operations;
11 | import reusableComponents.ExcelOperations;
12 | import testBase.ExtentFactory;
13 | import testBase.TestBase;
14 |
15 | /**
16 | * @author: Prakash Narkhede
17 | * @Youtube: https://www.youtube.com/automationtalks
18 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
19 | */
20 |
21 | public class TestCase extends TestBase{
22 | LoginPageObjects loginPage = new LoginPageObjects();
23 | HomePageObjects homePage = new HomePageObjects();
24 | TaskPageObjects taskPage = new TaskPageObjects();
25 | DB_Operations dbOps = new DB_Operations();
26 |
27 | ExcelOperations excel = new ExcelOperations("TaskCreationData");
28 |
29 | @Test(dataProvider = "taskCreationData")
30 | public void TaskCreationTest(Object obj1) throws Throwable {
31 | @SuppressWarnings("unchecked")
32 | HashMap testData = (HashMap) obj1;
33 |
34 | ExtentFactory.getInstance().getExtent().info("Test Data for this execution run is: "+ testData);
35 |
36 | loginPage.login(testData.get("UserName"), testData.get("Password"));
37 | //check if dashboard page opens
38 | homePage.checkIfDashBoardPageIsOpened();
39 | homePage.clickOnSideSubMenu("Tasks", "Add Task");
40 | //add task
41 | taskPage.createTask(testData);
42 | //verify task on UI
43 | taskPage.Search_Verify_TaskCreationOnUI(testData);
44 |
45 | //verify DB
46 | String sql = "SELECT * FROM `tasks` where name = '"+testData.get("TaskName")+"'";
47 | HashMap dbData = dbOps.getSqlResultInMap(sql);
48 | String TaskName = dbData.get("name");
49 | assertEqualsString_custom("taskFailureName", TaskName, "DB_Task_Name");
50 |
51 |
52 | }
53 |
54 | //Dataprovider method --> return object array
55 | @DataProvider (name = "taskCreationData")
56 | public Object[][] testDataSupplier() throws Exception {
57 | Object[][] obj = new Object[excel.getRowCount()][1];
58 | for (int i = 1; i <= excel.getRowCount(); i++) {
59 | HashMap testData = excel.getTestDataInMap(i);
60 | obj[i-1][0] = testData;
61 | }
62 | return obj;
63 |
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/test/java/Tests/UserLoginTests.java:
--------------------------------------------------------------------------------
1 | package Tests;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | import pageObjects.LoginPageObjects;
6 | import testBase.TestBase;
7 |
8 | /**
9 | * @author: Prakash Narkhede
10 | * @Youtube: https://www.youtube.com/automationtalks
11 | * @LinkedIn: https://www.linkedin.com/in/panarkhede89/
12 | */
13 | @Test
14 | public class UserLoginTests extends TestBase{
15 | LoginPageObjects loginPage = new LoginPageObjects();
16 |
17 |
18 | public void ManagerLoginTest() throws Throwable {
19 |
20 | loginPage.login("manager@localhost.com", "admin@123");
21 | Thread.sleep(2000); ////// not required, adding just to see tests are running in parallel
22 |
23 |
24 | }
25 | public void ClientLoginTest() throws Throwable {
26 |
27 | loginPage.login("client@localhost.com", "admin@123");
28 | Thread.sleep(2000); ////// not required, adding just to see tests are running in parallel
29 |
30 | }
31 | public void DesignerLoginTest() throws Throwable {
32 |
33 | loginPage.login("designer@localhost.com", "admin@123");
34 | Thread.sleep(2000); ////// not required, adding just to see tests are running in parallel
35 | assertEqualsString_custom("ExpectedTest", "ActualText", "LoginPageHomePage");
36 |
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/resources/config.properties:
--------------------------------------------------------------------------------
1 | browser= firefox
2 | url=http://192.168.225.219:8090/index.php/login
3 | testDataLocation = //src//test//resources//testData//TaskCreationTestData.xlsx
4 |
5 |
6 | retryCount=0
7 |
8 | ### ON or OFF
9 | automatic_Issue_Creation_In_JIRA=OFF
10 |
11 | ##### jira issues creation Credentials
12 | jiraURL=https://automationtalks.atlassian.net
13 | jiraUserName=prakashnarkhede89@gmail.com
14 | jiraSecretKey=1axLRL9dNZvN0R3FIzGh6354
--------------------------------------------------------------------------------
/src/test/resources/testData/TaskCreationTestData.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prakashnarkhede/Advanced_Selenium_Test_Automation_Framework/87ffe6e3b1a08da28e95fa950a7b5b48c7ba8d7f/src/test/resources/testData/TaskCreationTestData.xlsx
--------------------------------------------------------------------------------
/testng.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------