├── src
├── test
│ ├── resources
│ │ ├── testdata.xlsx
│ │ └── login.json
│ └── java
│ │ └── com
│ │ └── qed42
│ │ └── qa
│ │ ├── tests
│ │ ├── LoginExampleTest.java
│ │ ├── BaseTest.java
│ │ ├── JsonExampleTest.java
│ │ └── ExcelExampleTest.java
│ │ └── pageobjects
│ │ └── LoginExamplePage.java
└── main
│ ├── resources
│ └── log4j2.properties
│ └── java
│ └── com
│ └── qed42
│ └── qa
│ ├── configurations
│ └── Configuration.java
│ ├── utilities
│ ├── PropertiesFileReader.java
│ ├── JsonFileReader.java
│ ├── TestListener.java
│ └── ExcelManager.java
│ ├── reportmanager
│ ├── ExtentManager.java
│ └── Report.java
│ └── driver
│ └── DriverManager.java
├── config.properties
├── testng.xml
├── .gitignore
├── README.md
└── pom.xml
/src/test/resources/testdata.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qed42/headway/HEAD/src/test/resources/testdata.xlsx
--------------------------------------------------------------------------------
/config.properties:
--------------------------------------------------------------------------------
1 | baseUrl = http://demo.guru99.com/test/newtours/login.php
2 | browser = chrome
3 |
4 | platformName = mac
5 | reportPath = ./reports/Report_
6 |
--------------------------------------------------------------------------------
/src/test/resources/login.json:
--------------------------------------------------------------------------------
1 | {
2 | "users": [
3 | {
4 | "username": "selenium@qa",
5 | "password": "qa@12345"
6 | },
7 | {
8 | "username": "selenium",
9 | "password": "qa@123"
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/src/main/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | status = error
2 | name = PropertiesConfig
3 |
4 | # appenders = console, file
5 | appenders = file
6 |
7 | # Appender for writing to console
8 | appender.console.type = Console
9 | appender.console.name = STDOUT
10 | appender.console.layout.type = PatternLayout
11 | appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
12 |
13 | # Appender for writing to a file
14 | appender.file.type = File
15 | appender.file.name = FileLogger
16 | appender.file.filename = reports/logfile.log
17 | appender.file.layout.type = PatternLayout
18 | appender.file.layout.pattern = %d [%t] %-5p %c - %m%n
19 |
20 | # Root logger option
21 | rootLogger.level = debug
22 | #rootLogger.appenderRefs = stdout, file
23 | rootLogger.appenderRefs = file
24 | #rootLogger.appenderRef.stdout.ref = STDOUT
25 | rootLogger.appenderRef.file.ref = FileLogger
26 |
--------------------------------------------------------------------------------
/testng.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
25 |
26 |
--------------------------------------------------------------------------------
/src/main/java/com/qed42/qa/configurations/Configuration.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.configurations;
2 |
3 | import java.util.Properties;
4 | import com.qed42.qa.utilities.PropertiesFileReader;
5 |
6 | /**
7 | * Configuration is an interface that stores application related specific keys
8 | * which can be used as constant for configuration of the application
9 | *
10 | * @author QED42
11 | *
12 | */
13 | public interface Configuration {
14 |
15 | public static final String PROJECT_DIR = System.getProperty("user.dir");
16 | public static final Properties config = PropertiesFileReader.read(PROJECT_DIR + "/config.properties");
17 |
18 | public static final String BASE_URL = config.getProperty("baseUrl");
19 | public static final String BROWSER_NAME = config.getProperty("browser");
20 | public static final String PLATFORM_NAME = config.getProperty("platformName");
21 |
22 | public static final String MAIN_RESOURCE_PATH = PROJECT_DIR + "/src/main/resources/";
23 | public static final String TEST_RESOURCE_PATH = PROJECT_DIR + "/src/test/resources/";
24 |
25 | public static final String REPORT_PATH = config.getProperty("reportPath");
26 | }
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | test-output/
3 | reports/
4 | screenshots/
5 | .idea/
6 | .DS_Store
7 |
8 | # Package Files #
9 | *.jar
10 | *.war
11 | *.nar
12 | *.ear
13 | *.zip
14 | *.tar.gz
15 | *.rar
16 |
17 | ### Java ###
18 | # Compiled class file
19 | *.class
20 | .classpath
21 |
22 | # Log file
23 | *.log
24 |
25 | ### Eclipse ###
26 | .metadata
27 | bin/
28 | tmp/
29 | *.tmp
30 | *.bak
31 | *.swp
32 | *~.nib
33 | local.properties
34 | .settings/
35 | .loadpath
36 | .recommenders
37 |
38 | # Code Recommenders
39 | .recommenders/
40 |
41 | # Annotation Processing
42 | .apt_generated/
43 |
44 | # Scala IDE specific (Scala & Java development for Eclipse)
45 | .cache-main
46 | .scala_dependencies
47 | .worksheet
48 |
49 | ### Eclipse Patch ###
50 | # Eclipse Core
51 | .project
52 |
53 | # JDT-specific (Eclipse Java Development Tools)
54 | .classpath
55 |
56 | # Annotation Processing
57 | .apt_generated
58 |
59 | .sts4-cache/
60 |
61 | ### Maven ###
62 | pom.xml.tag
63 | pom.xml.releaseBackup
64 | pom.xml.versionsBackup
65 | pom.xml.next
66 | release.properties
67 | dependency-reduced-pom.xml
68 | buildNumber.properties
69 | .mvn/timing.properties
70 | .mvn/wrapper/maven-wrapper.jar
71 |
--------------------------------------------------------------------------------
/src/main/java/com/qed42/qa/utilities/PropertiesFileReader.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.utilities;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.util.Properties;
7 |
8 | /**
9 | * PropertiesFileReader class reads properties files and returns instance of "Properties" class.
10 | * It provides one method - read(fileName), which take filepath as the parameter.
11 | *
12 | * @author QED42
13 | *
14 | */
15 | public class PropertiesFileReader {
16 | public static Properties properties;
17 |
18 | /**
19 | * Reads properties file and returns instance of Properties class
20 | *
21 | * @param fileName
22 | * @return
23 | */
24 | public static Properties read(String fileName) {
25 | try {
26 | properties = new Properties();
27 | FileInputStream ip = new FileInputStream(fileName);
28 | properties.load(ip);
29 | } catch (FileNotFoundException e) {
30 | // TODO Auto-generated catch block
31 | e.printStackTrace();
32 | System.out.println("File not found");
33 | } catch (IOException e) {
34 | System.out.println("IO Exception");
35 | }
36 | return properties;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/com/qed42/qa/tests/LoginExampleTest.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.tests;
2 |
3 | import org.testng.Assert;
4 | import org.testng.annotations.Listeners;
5 | import org.testng.annotations.Test;
6 | import com.aventstack.extentreports.Status;
7 | import com.qed42.qa.driver.DriverManager;
8 | import com.qed42.qa.pageobjects.LoginExamplePage;
9 | import com.qed42.qa.reportmanager.Report;
10 |
11 | @Listeners(com.qed42.qa.utilities.TestListener.class)
12 |
13 | public class LoginExampleTest extends BaseTest {
14 |
15 | @Test
16 | public void testLoginValidInput() throws Exception {
17 | LoginExamplePage obj1 = new LoginExamplePage(DriverManager.getDriver());
18 | obj1.login("selenium@qa","qa@12345");
19 | Report.log(Status.PASS, "Login is successful");
20 | Assert.assertEquals(obj1.getPageCurrentUrl(), "https://demo.guru99.com/test/newtours/login_sucess.php");
21 | }
22 |
23 | @Test
24 | public void testLoginInvalidInput() throws Exception {
25 | LoginExamplePage obj2 = new LoginExamplePage(DriverManager.getDriver());
26 | obj2.login("selenium", "qa@123");
27 | Report.log(Status.FAIL, "Login unsuccessful");
28 | Assert.assertEquals(obj2.getPageCurrentUrl(), "https://demo.guru99.com/test/newtours/login_sucess.php");
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/com/qed42/qa/tests/BaseTest.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.tests;
2 |
3 | import org.testng.annotations.AfterClass;
4 | import org.testng.annotations.AfterMethod;
5 | import org.testng.annotations.BeforeMethod;
6 | import org.testng.annotations.Listeners;
7 | import org.testng.annotations.Optional;
8 | import org.testng.annotations.Parameters;
9 |
10 | import com.qed42.qa.driver.DriverManager;
11 |
12 | @Listeners(com.qed42.qa.utilities.TestListener.class)
13 |
14 | public class BaseTest {
15 |
16 | /**
17 | * This method initializes the driver and launches browser. It maximizes the browser window.
18 | * It is called before each test.
19 | *
20 | * @param browser
21 | */
22 | @Parameters({ "browser" })
23 | @BeforeMethod
24 | public void init(@Optional("chrome") String browser) {
25 | DriverManager.initialize(browser);
26 | }
27 |
28 | /**
29 | * quit() method is called after every test. It closes the browser
30 | *
31 | */
32 | @AfterMethod
33 | public void quit() {
34 | DriverManager.quit();
35 |
36 | }
37 |
38 | /**
39 | * terminate() method is called after every class. It removes the ThreadLocal driver.
40 | */
41 | @AfterClass
42 | public void tearDown() {
43 | DriverManager.terminate();
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/test/java/com/qed42/qa/pageobjects/LoginExamplePage.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.pageobjects;
2 |
3 | import org.openqa.selenium.By;
4 | import org.openqa.selenium.WebDriver;
5 | import com.aventstack.extentreports.Status;
6 | import com.qed42.qa.configurations.Configuration;
7 | import com.qed42.qa.reportmanager.Report;
8 |
9 | public class LoginExamplePage {
10 |
11 | WebDriver driver;
12 |
13 | public By txtUserName = By.name("userName");
14 | public By txtPassword = By.name("password");
15 | public By btnSubmit = By.name("submit");
16 |
17 | public LoginExamplePage(WebDriver driver) {
18 | this.driver = driver;
19 | }
20 |
21 | /**
22 | * Login with valid credentials
23 | *
24 | * @param userName
25 | * @param password
26 | * @throws Exception
27 | */
28 | public void login(String userName, String password) throws Exception {
29 | driver.get(Configuration.BASE_URL);
30 | Report.log(Status.PASS, "Navigated to the login page");
31 | driver.findElement(txtUserName).sendKeys(userName);
32 | driver.findElement(txtPassword).sendKeys(password);
33 | driver.findElement(btnSubmit).click();
34 | }
35 |
36 | /**
37 | *
38 | * @return
39 | * @throws Exception
40 | */
41 | public String getPageCurrentUrl() throws Exception {
42 | return driver.getCurrentUrl();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/qed42/qa/utilities/JsonFileReader.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.utilities;
2 |
3 | import java.io.FileReader;
4 | import org.json.simple.JSONArray;
5 | import org.json.simple.JSONObject;
6 | import org.json.simple.parser.JSONParser;
7 |
8 | /**
9 | * JSONFileReader class reads a JSON file
10 | *
11 | * @author QED42
12 | *
13 | */
14 | public class JsonFileReader {
15 |
16 | /**
17 | * Reads JSON file and returns JSONArray
18 | *
19 | * @param fileName
20 | * @return JSONObject
21 | * @throws Exception
22 | */
23 |
24 | public JSONObject readJson(String filename) throws Exception {
25 | JSONParser jsonParser = new JSONParser();
26 | FileReader filereader = new FileReader((filename));
27 |
28 | JSONObject obj = (JSONObject) jsonParser.parse(filereader);
29 | return obj;
30 | }
31 |
32 | /**
33 | * Reads JSON file and returns JSONArray with specific sets of JSON key
34 | *
35 | * @param filename
36 | * @param JSONkey
37 | * @return
38 | * @throws Exception
39 | */
40 | public JSONArray readJson(String filename, String JSONkey) throws Exception {
41 | JSONParser jsonParser = new JSONParser();
42 | FileReader filereader = new FileReader((filename));
43 |
44 | JSONObject obj = (JSONObject) jsonParser.parse(filereader);
45 | JSONArray arr = (JSONArray) obj.get(JSONkey);
46 | return arr;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/com/qed42/qa/tests/JsonExampleTest.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.tests;
2 |
3 | import org.testng.annotations.Test;
4 | import org.json.simple.JSONArray;
5 | import org.json.simple.JSONObject;
6 | import org.testng.Assert;
7 | import org.testng.annotations.DataProvider;
8 | import org.testng.annotations.Listeners;
9 | import com.aventstack.extentreports.Status;
10 | import com.qed42.qa.configurations.Configuration;
11 | import com.qed42.qa.driver.DriverManager;
12 | import com.qed42.qa.pageobjects.LoginExamplePage;
13 | import com.qed42.qa.reportmanager.Report;
14 | import com.qed42.qa.utilities.JsonFileReader;
15 |
16 | @Listeners(com.qed42.qa.utilities.TestListener.class)
17 |
18 | public class JsonExampleTest extends BaseTest {
19 |
20 | @Test(dataProvider = "userData")
21 | public void testJsonLogin(String username, String password) throws Exception {
22 | LoginExamplePage obj = new LoginExamplePage(DriverManager.getDriver());
23 |
24 | obj.login(username, password);
25 | Assert.assertEquals(obj.getPageCurrentUrl(), "https://demo.guru99.com/test/newtours/login_sucess.php");
26 | Report.log(Status.PASS, "Login Successful");
27 | }
28 |
29 | @DataProvider
30 | public Object[][] userData() throws Exception {
31 | JsonFileReader jsonReader = new JsonFileReader();
32 | JSONArray usersList = jsonReader.readJson(Configuration.TEST_RESOURCE_PATH + "/login.json", "users");
33 | Object[][] dataObj = new Object[usersList.size()][2];
34 |
35 | for (int i = 0; i < dataObj.length; i++) {
36 | JSONObject user = (JSONObject) usersList.get(i);
37 | dataObj[i][0] = user.get("username");
38 | dataObj[i][1] = user.get("password");
39 | }
40 | return dataObj;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/qed42/qa/reportmanager/ExtentManager.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.reportmanager;
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.ExtentSparkReporterConfig;
9 | import com.aventstack.extentreports.reporter.configuration.Theme;
10 | import com.qed42.qa.configurations.Configuration;
11 |
12 | /**
13 | * ExtentManager class implements Configuration interface.
14 | * In this class, we create an ExtentReports object which can be reachable via getExtentReports() method.
15 | * Also, we set ExtentReports report HTML file location.
16 | *
17 | */
18 | public class ExtentManager implements Configuration {
19 |
20 | private static ExtentReports extentreport;
21 |
22 | /**
23 | * getExtentReports() is a static method that creates and configures ExtenetReports object.
24 | * This method sets the theme of the report to STANDARD and title to "Test Report".
25 | *
26 | * @return
27 | */
28 | public synchronized static ExtentReports getExtentReports() {
29 | if (extentreport == null) {
30 | // String date = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
31 | String date = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss").format(new Date());
32 | ExtentSparkReporter htmlreporter = new ExtentSparkReporter(REPORT_PATH + date);
33 | extentreport = new ExtentReports();
34 | extentreport.attachReporter(htmlreporter);
35 | htmlreporter.config(
36 | ExtentSparkReporterConfig.builder().theme(Theme.STANDARD).documentTitle("Test Report").build());
37 | }
38 | return extentreport;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/java/com/qed42/qa/tests/ExcelExampleTest.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.tests;
2 |
3 | import org.testng.Assert;
4 | import org.testng.annotations.DataProvider;
5 | import org.testng.annotations.Listeners;
6 | import org.testng.annotations.Test;
7 | import java.util.ArrayList;
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import com.aventstack.extentreports.Status;
11 | import com.codoid.products.exception.FilloException;
12 | import com.qed42.qa.configurations.Configuration;
13 | import com.qed42.qa.driver.DriverManager;
14 | import com.qed42.qa.pageobjects.LoginExamplePage;
15 | import com.qed42.qa.reportmanager.Report;
16 | import com.qed42.qa.utilities.ExcelManager;
17 |
18 | @Listeners(com.qed42.qa.utilities.TestListener.class)
19 |
20 | public class ExcelExampleTest extends BaseTest {
21 | ArrayList loginCreds = new ArrayList();
22 |
23 | @Test(dataProvider = "userData")
24 | public void testExcelLogin(String username, String password) throws Exception {
25 | LoginExamplePage obj = new LoginExamplePage(DriverManager.getDriver());
26 | obj.login(username, password);
27 | Assert.assertEquals(obj.getPageCurrentUrl(), "https://demo.guru99.com/test/newtours/login_sucess.php");
28 | Report.log(Status.PASS, "Login successful");
29 | }
30 |
31 | @DataProvider
32 | public Object[][] userData() throws FilloException {
33 | ExcelManager fillo = new ExcelManager();
34 | List> users = fillo.getAllData(Configuration.TEST_RESOURCE_PATH, "testdata.xlsx", "TestData");
35 | Object[][] dataObj = new Object[users.size()][2];
36 |
37 | for (int i = 0; i < users.size(); i++) {
38 | dataObj[i][0] = users.get(i).get("Username");
39 | dataObj[i][1] = users.get(i).get("Password");
40 | }
41 | return dataObj;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Headway - Selenium Data Driven Framework
2 |
3 | Headway is a data-driven testing framework that uses Selenium to automate web-based applications. It is designed to simplify the process of creating and executing automated tests by separating test data from test logic.
4 |
5 | ********************************************************************************
6 |
7 | ## Features
8 |
9 | 1. Data-driven approach: Test data is stored separately from the test scripts, allowing for easy modification and reuse of test cases.
10 | 2. Modularity: The framework is built using a modular approach, making it easy to add or remove functionality as needed.
11 | 3. Reporting: The framework generates detailed test reports in HTML format, making it easy to track test results and identify issues.
12 | 4. Cross-browser compatibility: The framework supports testing on multiple browsers, including Chrome, Firefox, and Safari.
13 | 5. Parallel testing: The framework supports parallel execution of test cases, reducing the overall test execution time
14 |
15 | ## Requirements
16 |
17 | 1. Java 8 or higher
18 | 2. Maven 3.x
19 | 3. Selenium WebDriver
20 | 4. TestNG
21 | 5. Eclipse
22 |
23 |
24 | ## Installations
25 |
26 | 1. Clone this repository to your local machine.
27 | 2. Install the required dependencies by running mvn clean install in the root directory
28 | OR
29 | Import project as an existing Maven project in Eclipse, File > Import > Maven > Existing Maven Projects > Next >
30 | a. Browse to headway
31 | b. Ensure pom.xml is found
32 | c. Finish.
33 | 3. Update the config.properties file to configure the test settings such as the browser type and test URL.
34 | 4. Write your test cases in the src/test/java directory using TestNG annotation and POM design pattern.
35 |
36 |
37 | ## Contribution
38 |
39 | Contributions are welcome! Please feel free to open a pull request or submit an issue if you find any bugs or have any suggestions for improvement.
40 |
--------------------------------------------------------------------------------
/src/main/java/com/qed42/qa/reportmanager/Report.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.reportmanager;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import com.aventstack.extentreports.ExtentReports;
6 | import com.aventstack.extentreports.ExtentTest;
7 | import com.aventstack.extentreports.Status;
8 |
9 | /**
10 | * extentTestMap holds the information of thread ids and ExtentTest instances.
11 | * ExtentReports instance created by calling getExtentReports() method from ExtentManager.
12 | * At startTest() method, an instance of ExtentTest is created and put into extentTestMap with current thread id.
13 | * At getTest() method, return ExtentTest instance in extentTestMap by using current thread id.
14 | *
15 | */
16 | public class Report {
17 | static Map extentTestMap = new HashMap<>();
18 | private static ExtentReports extent = ExtentManager.getExtentReports();
19 | static ExtentTest test;
20 |
21 | public static synchronized ExtentTest getTest() {
22 | return extentTestMap.get((int) (long) (Thread.currentThread().getId()));
23 | }
24 |
25 | public static synchronized ExtentTest startTest(String testName) {
26 | return startTest(testName, "");
27 | }
28 |
29 | public static synchronized ExtentTest startTest(String testName, String desc) {
30 | test = extent.createTest(testName, desc);
31 | extentTestMap.put((int) (long) (Thread.currentThread().getId()), test);
32 | return test;
33 | }
34 |
35 | public static synchronized void endTest() {
36 | extent.flush();
37 | }
38 |
39 | public static synchronized void log(Status status, String desc, String methodName) {
40 | System.out.println(methodName + " : " + desc);
41 | Report.getTest().log(status, desc);
42 | }
43 |
44 | public static synchronized void log(Status status, String desc) {
45 | System.out.println("Thread Id : " + Thread.currentThread().getId() + " " + desc);
46 | Report.getTest().log(status, desc);
47 | }
48 |
49 | public static synchronized void log(Status status, Exception e) {
50 | Report.getTest().log(status, e);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/qed42/qa/utilities/TestListener.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.utilities;
2 |
3 | import java.io.File;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 | import org.apache.commons.io.FileUtils;
7 | import org.apache.logging.log4j.LogManager;
8 | import org.apache.logging.log4j.Logger;
9 | import org.testng.ITestContext;
10 | import org.testng.ITestListener;
11 | import org.testng.ITestResult;
12 | import com.aventstack.extentreports.Status;
13 | import com.qed42.qa.driver.DriverManager;
14 | import com.qed42.qa.reportmanager.Report;
15 | import org.openqa.selenium.OutputType;
16 | import org.openqa.selenium.TakesScreenshot;
17 |
18 | /**
19 | * TestListener class implements ITestListener interface.
20 | * We have added Extent Reports codes in each method.
21 | * This class is used to generate logs or customize the TestNG reports.
22 | *
23 | */
24 | public class TestListener implements ITestListener {
25 |
26 | static Logger log = LogManager.getLogger(Report.class);
27 |
28 | public void onTestStart(ITestResult result) {
29 | System.out.println("\n" + " ***** Test Executing : " + result.getName());
30 | log.info(" ***** Test Executing : " + result.getName());
31 | Report.startTest(result.getMethod().getMethodName(), result.getMethod().getDescription());
32 | }
33 |
34 | public void onTestSuccess(ITestResult result) {
35 | log.info("Test Passed : " + result.getName());
36 | Report.log(Status.PASS, " Test Passed", result.getName());
37 | }
38 |
39 | public void onTestFailure(ITestResult result) {
40 | log.info("Test Failed : " + result.getName());
41 | try {
42 |
43 | // String date = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
44 | String date = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss").format(new Date());
45 |
46 | //Object currentInstance = result.getInstance();
47 | TakesScreenshot ts = (TakesScreenshot) (DriverManager.getDriver());
48 |
49 | File source = ts.getScreenshotAs(OutputType.FILE);
50 | String destination = System.getProperty("user.dir") + "/screenshots/" + result.getName() + "_" + date + ".png";
51 | File finalDestination = new File(destination);
52 |
53 | FileUtils.copyFile(source, finalDestination);
54 |
55 | Report.log(Status.FAIL, " Test Failed " + result.getThrowable(), result.getName());
56 | Report.getTest().addScreenCaptureFromPath(destination);
57 | } catch (Exception e) {
58 | // TODO Auto-generated catch block
59 | e.printStackTrace();
60 | }
61 | }
62 |
63 | public void onTestSkipped(ITestResult result) {
64 | log.info("Test Skipped : " + result.getName());
65 | Report.log(Status.SKIP, " Test Skipped " + result.getThrowable(), result.getName());
66 | }
67 |
68 | public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
69 | // System.out.println("Test Failed but within success percentage : " +
70 | // result.getName());
71 | }
72 |
73 | public void onStart(ITestContext context) {
74 | System.out.println("\n" + "---------------- TEST EXECUTION STARTED ---------------- ");
75 | }
76 |
77 | public void onFinish(ITestContext context) {
78 | Report.endTest();
79 | System.out.println("\n" + "---------------- TEST EXECUTION FINISHED ---------------- ");
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 | com.qed42
7 | headway
8 | 0.0.1-SNAPSHOT
9 |
10 | headway
11 |
12 | http://www.example.com
13 |
14 |
15 | UTF-8
16 | 11
17 |
18 |
19 |
20 |
21 | org.seleniumhq.selenium
22 | selenium-java
23 | 4.11.0
24 |
25 |
26 | org.testng
27 | testng
28 | 7.4.0
29 |
30 |
31 |
32 | io.github.bonigarcia
33 | webdrivermanager
34 | 6.1.0
35 |
36 |
37 | com.aventstack
38 | extentreports
39 | 5.0.8
40 |
41 |
42 | org.apache.logging.log4j
43 | log4j-api
44 | 2.13.1
45 |
46 |
47 | org.apache.logging.log4j
48 | log4j-core
49 | 2.14.1
50 |
51 |
52 | com.codoid.products
53 | fillo
54 | 1.21
55 |
56 |
57 | com.googlecode.json-simple
58 | json-simple
59 | 1.1.1
60 |
61 |
62 |
63 | ch.qos.logback
64 | logback-classic
65 | 1.4.11
66 | compile
67 |
68 |
69 |
70 |
71 |
72 |
74 |
75 |
76 |
77 | maven-clean-plugin
78 | 3.1.0
79 |
80 |
81 |
82 | maven-resources-plugin
83 | 3.0.2
84 |
85 |
86 | maven-compiler-plugin
87 | 3.8.0
88 |
89 |
90 | maven-jar-plugin
91 | 3.0.2
92 |
93 |
94 | maven-install-plugin
95 | 2.5.2
96 |
97 |
98 | maven-deploy-plugin
99 | 2.8.2
100 |
101 |
102 |
103 | maven-site-plugin
104 | 3.7.1
105 |
106 |
107 | maven-project-info-reports-plugin
108 | 3.0.0
109 |
110 |
111 | org.apache.maven.plugins
112 | maven-surefire-plugin
113 | 3.0.0-M7
114 |
115 |
116 | testng.xml
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/src/main/java/com/qed42/qa/driver/DriverManager.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.driver;
2 |
3 | import java.time.Duration;
4 | import org.apache.logging.log4j.LogManager;
5 | import org.apache.logging.log4j.Logger;
6 | import org.openqa.selenium.WebDriver;
7 | import org.openqa.selenium.WebDriverException;
8 | import org.openqa.selenium.chrome.ChromeDriver;
9 | import org.openqa.selenium.chrome.ChromeOptions;
10 | import org.openqa.selenium.edge.EdgeDriver;
11 | import org.openqa.selenium.firefox.FirefoxDriver;
12 | import org.openqa.selenium.firefox.FirefoxOptions;
13 | import org.openqa.selenium.safari.SafariDriver;
14 | import com.qed42.qa.configurations.Configuration;
15 | import org.testng.annotations.Optional;
16 |
17 | /**
18 | * DriverManager class contains methods to initialise browser driver & launch browser before test execution
19 | * and quit the browser after test execution. Browser type is passed as parameter via testng.xml file.
20 | *
21 | */
22 | public class DriverManager {
23 |
24 | protected static ThreadLocal driver = new ThreadLocal<>();
25 | static Logger log = LogManager.getLogger(DriverManager.class);
26 |
27 | private DriverManager() {
28 | // To prevent external instantiation of this class
29 | }
30 |
31 | /**
32 | * This method is used to retrieve the driver and does not take any parameters.
33 | *
34 | * @return
35 | */
36 | public static WebDriver getDriver() {
37 | return driver.get();
38 | }
39 |
40 |
41 | /**
42 | * This method initializes the driver and launches browser. It maximizes the browser window.
43 | * It is called before each test.
44 | *
45 | * @param browser
46 | */
47 | public static void initialize(@Optional("chrome") String browser) {
48 | driver.set(getDriver(browser));
49 |
50 | log.info(browser.toUpperCase() + " is configured");
51 |
52 | getDriver().manage().window().maximize();
53 | getDriver().manage().deleteAllCookies();
54 |
55 | getDriver().manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
56 | getDriver().manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
57 | }
58 |
59 | /**
60 | * This method is used to retrieve the driver based on the browser parameter.
61 | * Supported browsers - Chrome, Chrome-headless Firefox, Firefox-headless, Safari and Edge.
62 | *
63 | * @param browserName
64 | * @return
65 | */
66 | public static WebDriver getDriver(String browserName) {
67 | WebDriver driver = null;
68 |
69 | switch (browserName) {
70 | case "chrome":
71 | driver = new ChromeDriver();
72 | break;
73 | case "chrome-headless":
74 | driver = new ChromeDriver(new ChromeOptions().addArguments("--headless=new"));
75 | break;
76 | case "firefox":
77 | driver = new FirefoxDriver();
78 | break;
79 | case "firefox-headless":
80 | driver = new FirefoxDriver(new FirefoxOptions().addArguments("-headless"));
81 | break;
82 | case "edge":
83 | if (Configuration.PLATFORM_NAME.toLowerCase().contains("mac")) {
84 | throw new WebDriverException("Your operating system does not support the requested browser");
85 | } else {
86 | driver = new EdgeDriver();
87 | }
88 | break;
89 | case "safari":
90 | if (Configuration.PLATFORM_NAME.toLowerCase().contains("windows")) {
91 | throw new WebDriverException("Your operating system does not support the requested browser");
92 | } else {
93 | driver = new SafariDriver();
94 | }
95 | break;
96 | default:
97 | System.out.println("No driver found for:" + browserName);
98 | }
99 | return driver;
100 | }
101 |
102 | /**
103 | * quit() method is called after every test. It closes the browser
104 | *
105 | */
106 | public static void quit() {
107 | getDriver().manage().deleteAllCookies();
108 | getDriver().close();
109 | }
110 |
111 | /**
112 | * terminate() method is called after every class. It removes the ThreadLocal driver.
113 | */
114 | public static void terminate() {
115 | driver.remove();
116 | }
117 |
118 | /*
119 | * Use below method when browser is passed as parameter in config.properties
120 | *
121 | * public void initialize() {
122 | * String browserName = properties.getProperty("browser");
123 | * driver.set(getDriver(browserName));
124 | *
125 | * log.info(browserName + " is configured");
126 | *
127 | * getDriver().manage().window().maximize();
128 | * getDriver().manage().deleteAllCookies();
129 | *
130 | * getDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
131 | * getDriver().manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
132 | *
133 | * }
134 | */
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/src/main/java/com/qed42/qa/utilities/ExcelManager.java:
--------------------------------------------------------------------------------
1 | package com.qed42.qa.utilities;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import com.codoid.products.exception.FilloException;
7 | import com.codoid.products.fillo.Connection;
8 | import com.codoid.products.fillo.Fillo;
9 | import com.codoid.products.fillo.Recordset;
10 |
11 | /**
12 | * Fillo library is used for reading and writing data with excel files (xlsx and xls) using SQL queries.
13 | * Create an instance of 'ExcelManager' class and access methods to read and data from/to excel.
14 | *
15 | * @author QED42
16 | *
17 | */
18 | public class ExcelManager {
19 |
20 | public String filepath1;
21 |
22 | /**
23 | * Performs "SELECT * From ". Returns all data from an excel sheet.
24 | *
25 | * @param filepath - Path of the excel file directory
26 | * @param excelName - Excel file name
27 | * @param sheetName - Sheet name in an excel file
28 | * @return
29 | * @throws FilloException
30 | */
31 | public List> getAllData(String filepath, String excelName, String sheetName)
32 | throws FilloException {
33 | Fillo fillo = new Fillo();
34 | filepath1 = filepath + excelName;
35 | List> recordList = new ArrayList<>();
36 |
37 | Connection connection = fillo.getConnection(filepath1);
38 | String strQuery = "Select * from" + " " + sheetName;
39 | Recordset recordset = connection.executeQuery(strQuery);
40 | int columnCount = recordset.getFieldNames().size();
41 |
42 | while (recordset.next()) {
43 | HashMap rowData = new HashMap();
44 |
45 | for (int i = 0; i <= columnCount - 1; i++) {
46 | String fieldKey = recordset.getFieldNames().get(i);
47 | String fieldValue = recordset.getField(fieldKey);
48 | rowData.put(fieldKey, fieldValue);
49 | }
50 | recordList.add(rowData);
51 | }
52 | recordset.close();
53 | connection.close();
54 | return recordList;
55 | }
56 |
57 | /**
58 | * Performs "SELECT * From Where ". Returns data that
59 | * meet the condition(s) given in where clause, from an excel sheet.
60 | *
61 | * @param filepath - Path of the excel file directory
62 | * @param excelName - Excel file name
63 | * @param sheetName - Sheet name in an excel file
64 | * @param whereClause - Mention single or multiple conditions. With or without
65 | * LIKE Operator ex. "Select * from Sheet1 where userName
66 | * like 'Cod%'"
67 | * @return
68 | * @throws FilloException
69 | */
70 | public List> getDataWithWhere(String filepath, String excelName, String sheetName,
71 | String whereClause) throws FilloException {
72 | Fillo fillo = new Fillo();
73 | filepath1 = filepath + excelName;
74 | List> recordList = new ArrayList<>();
75 |
76 | Connection connection = fillo.getConnection(filepath1);
77 | String strQuery = "Select * from" + " " + sheetName + " " + whereClause;
78 | Recordset recordset = connection.executeQuery(strQuery);
79 | int columnCount = recordset.getFieldNames().size();
80 |
81 | while (recordset.next()) {
82 | HashMap rowData = new HashMap();
83 |
84 | for (int i = 0; i <= columnCount - 1; i++) {
85 | String fieldKey = recordset.getFieldNames().get(i);
86 | String fieldValue = recordset.getField(fieldKey);
87 | rowData.put(fieldKey, fieldValue);
88 | }
89 | recordList.add(rowData);
90 | }
91 | recordset.close();
92 | connection.close();
93 | return recordList;
94 | }
95 |
96 | /**
97 | * Performs "SELECT * From Where
98 | * ". Returns data that meet the condition given in where clause, from an excel
99 | * sheet.
100 | *
101 | * @param filepath - Path of the excel file directory
102 | * @param excelName - Excel file name
103 | * @param sheetName - Sheet name in an excel file
104 | * @param fieldName - Column name
105 | * @param fieldValue - Column value
106 | * @param operator - ex. '=','!=','<','>','<=','>='
107 | * @return
108 | * @throws FilloException
109 | */
110 | public List> getDataWithWhere(String filepath, String excelName, String sheetName,
111 | String fieldName, String operator, String fieldValue) throws FilloException {
112 | Fillo fillo = new Fillo();
113 | filepath1 = filepath + excelName;
114 | List> recordList = new ArrayList<>();
115 |
116 | Connection connection = fillo.getConnection(filepath1);
117 | String strQuery = "Select * from" + " " + sheetName + " " + "where " + fieldName + operator + "'" + fieldValue
118 | + "'";
119 | Recordset recordset = connection.executeQuery(strQuery);
120 | int columnCount = recordset.getFieldNames().size();
121 |
122 | while (recordset.next()) {
123 | HashMap rowData = new HashMap();
124 |
125 | for (int i = 0; i <= columnCount - 1; i++) {
126 | String fieldKey = recordset.getFieldNames().get(i);
127 | String fieldValue1 = recordset.getField(fieldKey);
128 | rowData.put(fieldKey, fieldValue1);
129 | }
130 | recordList.add(rowData);
131 | }
132 | recordset.close();
133 | connection.close();
134 | return recordList;
135 | }
136 |
137 | /**
138 | * Performs "INSERT into" ( ) Values () ".
139 | * Inserts record into an excel sheet.
140 | *
141 | * @param filepath - Path of the excel file directory
142 | * @param excelName - Excel file name
143 | * @param sheetName - Sheet name in an excel file
144 | * @param fieldNames - Column names Ex. "Username,Password"
145 | * @param fieldValues - Column values Ex. "'abc','123'"
146 | * @return
147 | * @throws FilloException
148 | */
149 | public void insertRowData(String filepath, String excelName, String sheetName, String fieldNames,
150 | String fieldValues) throws FilloException {
151 |
152 | Fillo fillo = new Fillo();
153 | filepath1 = filepath + excelName;
154 |
155 | Connection connection = fillo.getConnection(filepath1);
156 | String strQuery = "INSERT into " + sheetName + " (" + fieldNames + ") Values(" + fieldValues + ")";
157 | connection.executeUpdate(strQuery);
158 | connection.close();
159 | }
160 |
161 | /**
162 | * Performs "UPDATE" set = where
163 | * ) ". Updates a field for records matching the condition given in
164 | * where clause.
165 | *
166 | * @param filepath - Path of the excel file directory
167 | * @param excelName - Excel file name
168 | * @param sheetName - Sheet name in an excel file
169 | * @param whereClause
170 | * @param fieldName - Column name Ex. "Username"
171 | * @param fieldValue - Column value Ex. "'abc'"
172 | * @return
173 | * @throws FilloException
174 | */
175 | public void updateDataWithWhere(String filepath, String excelName, String sheetName, String fieldName,
176 | String fieldValue, String whereClause) throws FilloException {
177 | Fillo fillo = new Fillo();
178 | filepath1 = filepath + excelName;
179 | Connection connection = fillo.getConnection(filepath);
180 |
181 | String strQuery = "Update " + sheetName + " set " + fieldName + "=" + fieldValue + " " + whereClause;
182 | connection.executeUpdate(strQuery);
183 | connection.close();
184 | }
185 |
186 | /**
187 | * Performs "UPDATE" set = where
188 | * ) ". Updates field of all records.
189 | *
190 | * @param filepath - Path of the excel file directory
191 | * @param excelName - Excel file name
192 | * @param sheetName - Sheet name in an excel file
193 | * @param fieldName - Column name Ex. "Username"
194 | * @param fieldValue - Column value Ex. "'abc'"
195 | * @return
196 | * @throws FilloException
197 | */
198 | public void updateData(String filepath, String excelName, String sheetName, String fieldName, String fieldValue)
199 | throws FilloException {
200 |
201 | Fillo fillo = new Fillo();
202 | filepath1 = filepath + excelName;
203 |
204 | Connection connection = fillo.getConnection(filepath);
205 | String strQuery = "Update " + sheetName + " set " + fieldName + "=" + fieldValue;
206 | connection.executeUpdate(strQuery);
207 | connection.close();
208 | }
209 |
210 | }
211 |
--------------------------------------------------------------------------------