├── .gitignore ├── README.md ├── pom.xml └── src └── test ├── java └── example │ └── example │ ├── context │ ├── Constants.java │ └── WebDriverContext.java │ ├── factory │ └── PageinstancesFactory.java │ ├── listeners │ ├── LogListener.java │ └── ReportListener.java │ ├── pages │ ├── BasePage.java │ ├── FacebookLoginPage.java │ └── GooglePage.java │ ├── report │ └── ExtentReportManager.java │ ├── tests │ ├── BaseTest.java │ ├── FaceBookLoginTest.java │ └── GoogleSearchTest.java │ └── util │ ├── LoggerUtil.java │ ├── MailUtil.java │ ├── ReportUtil.java │ └── TestProperties.java └── resources ├── config ├── extent-config.xml └── test.properties ├── log4j.xml └── suites └── testng.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | .project 3 | .classpath 4 | /.settings/ 5 | /ExtentReports/ 6 | logfile.log 7 | /test-output/ 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | selenium-testng-framework 2 | --- 3 | 4 | --- 5 | A sample framework based on Page Object Model, Selenium, TestNG using Java. 6 | 7 | This framework is based in **Page Object Model (POM).** 8 | 9 | The framework uses: 10 | 11 | 1. Java 12 | 2. Selenium 13 | 3. TestNG 14 | 4. ExtentReport 15 | 5. Log4j 16 | 6. SimpleJavaMail 17 | 18 | Steps to create test cases: 19 | ---- 20 | Let's say we want to automate Google search test. 21 | 22 | 1.Create GoogleSearchPage in **pages** package. 23 | A page class typically should contain all the elements that are present on the page and corresponding action methods. 24 | 25 | ``` 26 | public class GooglePage extends BasePage { 27 | 28 | @FindBy(name = "q") 29 | private WebElement searchinput; 30 | 31 | public GooglePage(WebDriver driver) { 32 | super(driver); 33 | } 34 | 35 | public void searchText(String key) { 36 | searchinput.sendKeys(key + Keys.ENTER); 37 | } 38 | 39 | } 40 | ``` 41 | 2.Create the test class which class the methods of GoogleSearchPage 42 | 43 | ``` 44 | @Test(testName = "Google search test", description = "Test description") 45 | public class GoogleSearchTest extends BaseTest { 46 | 47 | @Test 48 | public void googleSearchTest() { 49 | driver.get("https://www.google.co.in/"); 50 | GooglePage googlePage = PageinstancesFactory.getInstance(GooglePage.class); 51 | googlePage.searchText("abc"); 52 | Assert.assertTrue(driver.getTitle().contains("abc"), "Title doesn't contain abc : Test Failed"); 53 | } 54 | } 55 | ``` 56 | 3.Add the test class in testng.xml file under the folder `src/test/resources/suites/` 57 | 58 | ``` 59 | 60 | 61 | 62 | 63 | 64 | ``` 65 | 4.Execute the test cases by maven command `mvn clean test` 66 | 67 | --- 68 | 69 | Reproting 70 | --- 71 | The framework gives report in three ways, 72 | 73 | 1. Log - In file `logfile.log`. 74 | 2. A html report - Which is generated using extent reports, under the folder `ExtentReports`. 75 | 3. A mail report - For which the toggle `mail.sendmail` in `test.properties` should be set `true`. And all the properties such as `smtp host, port, proxy details, etc.,` should be provided correctly. 76 | 77 | --- 78 | 79 | Key Points: 80 | --- 81 | 82 | 1. The class `WebDriverContext` is responsible for maintaining the same WebDriver instance throughout the test. So whenever you require a webdriver instance which has been using for current test (In current thread) always call `WebDriverContext.getDriver()`. 83 | 2. Always use `PageinstancesFactory.getInstance(type)` to get the instance of particular Page Object. (Of course you can use `new` but it's better use a single approach across the framework. 84 | 85 | --- 86 | 87 | >For any query or suggestions please do comment or mail @ diggavibharathish@gmail.com 88 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | example 7 | selenium-testng-framework 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | selenium-testng-framework 12 | http://maven.apache.org 13 | 14 | 15 | UTF-8 16 | 1.8 17 | 1.8 18 |

x

19 |
20 | 21 | 22 | 23 | 24 | org.seleniumhq.selenium 25 | selenium-java 26 | 3.141.59 27 | 28 | 29 | 30 | org.testng 31 | testng 32 | 6.14.3 33 | test 34 | 35 | 36 | 37 | com.relevantcodes 38 | extentreports 39 | 2.41.2 40 | 41 | 42 | 43 | log4j 44 | log4j 45 | 1.2.17 46 | 47 | 48 | 49 | org.simplejavamail 50 | simple-java-mail 51 | 5.1.1 52 | 53 | 54 | 55 | io.github.bonigarcia 56 | webdrivermanager 57 | 4.3.1 58 | 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-surefire-plugin 65 | 2.19.1 66 | 67 | 68 | ./src/test/resources/suites/testng.xml 69 | 70 | 71 | 72 | 73 | 74 |
75 | -------------------------------------------------------------------------------- /src/test/java/example/example/context/Constants.java: -------------------------------------------------------------------------------- 1 | package example.example.context; 2 | 3 | /** 4 | * The Class is for Constants. 5 | * 6 | * @author Bharathish 7 | */ 8 | public class Constants { 9 | 10 | /** The Constant WORKING_DIRECTORY. */ 11 | public static final String WORKING_DIRECTORY = System.getProperty("user.dir"); 12 | 13 | /** The Constant REPORT_DIRECTORY. */ 14 | public final static String REPORT_DIRECTORY = WORKING_DIRECTORY + "/ExtentReports/AutomationResult.html"; 15 | 16 | /** The Constant PROJECT_NAME. */ 17 | public final static String PROJECT_NAME = "Your_Project_Name"; 18 | 19 | /** The Constant EXTENT_CONFIG_PATH. */ 20 | public final static String EXTENT_CONFIG_PATH = WORKING_DIRECTORY + "/src/test/resources/config/extent-config.xml"; 21 | 22 | /** The Constant PROPERTY_FILE_PATH. */ 23 | public final static String PROPERTY_FILE_PATH = WORKING_DIRECTORY + "/src/test/resources/config/test.properties"; 24 | 25 | /** The Constant CHROME_DRIVER_PATH. */ 26 | public final static String CHROME_DRIVER_PATH = WORKING_DIRECTORY + "/src/test/resources/drivers/chromedriver.exe"; 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/example/example/context/WebDriverContext.java: -------------------------------------------------------------------------------- 1 | package example.example.context; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | 5 | /** 6 | * The Class is responsible in maintaining single instance of webdriver in any given thread. 7 | * 8 | * @author Bharathish 9 | */ 10 | public class WebDriverContext { 11 | 12 | /** The driverinstance. */ 13 | private static InheritableThreadLocal driverinstance = new InheritableThreadLocal<>(); 14 | 15 | /** 16 | * Gets the driver. 17 | * 18 | * @return the driver 19 | */ 20 | public static WebDriver getDriver() { 21 | if (driverinstance.get() == null) 22 | throw new IllegalStateException( 23 | "WebDriver has not been set, Please set WebDriver instance by WebDriverContext.setDriver..."); 24 | else 25 | return driverinstance.get(); 26 | } 27 | 28 | /** 29 | * Sets the driver. 30 | * 31 | * @param driver the new driver 32 | */ 33 | public static void setDriver(WebDriver driver) { 34 | driverinstance.set(driver); 35 | } 36 | 37 | /** 38 | * Removes the driver. 39 | */ 40 | public static void removeDriver() { 41 | driverinstance.remove(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/example/example/factory/PageinstancesFactory.java: -------------------------------------------------------------------------------- 1 | package example.example.factory; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | 7 | import example.example.context.WebDriverContext; 8 | import example.example.pages.BasePage; 9 | 10 | /** 11 | * A factory for creating Pageinstances objects. 12 | */ 13 | public class PageinstancesFactory { 14 | 15 | /** 16 | * Gets the single instance of PageinstancesFactory. 17 | * 18 | * @param the generic type 19 | * @param type the type 20 | * @return single instance of PageinstancesFactory 21 | */ 22 | public static T getInstance(Class type) { 23 | try { 24 | return type.getConstructor(WebDriver.class).newInstance(WebDriverContext.getDriver()); 25 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 26 | | NoSuchMethodException | SecurityException e) { 27 | e.printStackTrace(); 28 | return null; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/example/example/listeners/LogListener.java: -------------------------------------------------------------------------------- 1 | package example.example.listeners; 2 | 3 | import org.testng.ITestContext; 4 | import org.testng.ITestListener; 5 | import org.testng.ITestResult; 6 | 7 | import example.example.util.LoggerUtil; 8 | 9 | /** 10 | * The listener interface for receiving log events. The class that is interested 11 | * in processing a log event implements this interface, and the object created 12 | * with that class is registered with a component using the component's 13 | * addLogListener method. When the log event occurs, that object's 14 | * appropriate method is invoked. 15 | * 16 | * @see LogEvent 17 | */ 18 | public class LogListener implements ITestListener { 19 | 20 | /** 21 | * Gets the test name. 22 | * 23 | * @param result the result 24 | * @return the test name 25 | */ 26 | public String getTestName(ITestResult result) { 27 | return result.getTestName() != null ? result.getTestName() 28 | : result.getMethod().getConstructorOrMethod().getName(); 29 | } 30 | 31 | /** 32 | * Gets the test description. 33 | * 34 | * @param result the result 35 | * @return the test description 36 | */ 37 | public String getTestDescription(ITestResult result) { 38 | return result.getMethod().getDescription() != null ? result.getMethod().getDescription() : getTestName(result); 39 | } 40 | 41 | @Override 42 | public void onTestStart(ITestResult result) { 43 | LoggerUtil.log(getTestName(result) + ": Test started"); 44 | } 45 | 46 | @Override 47 | public void onTestSuccess(ITestResult result) { 48 | LoggerUtil.log(getTestName(result) + " : Test Passed"); 49 | } 50 | 51 | @Override 52 | public void onTestFailure(ITestResult result) { 53 | Throwable t = result.getThrowable(); 54 | String cause = ""; 55 | if (t != null) 56 | cause = t.getMessage(); 57 | LoggerUtil.getLogger().fatal(getTestName(result) + " : Test Failed : " + cause); 58 | } 59 | 60 | @Override 61 | public void onTestSkipped(ITestResult result) { 62 | LoggerUtil.log(getTestName(result) + " : Test Skipped"); 63 | } 64 | 65 | @Override 66 | public void onTestFailedButWithinSuccessPercentage(ITestResult result) { 67 | } 68 | 69 | @Override 70 | public void onStart(ITestContext context) { 71 | } 72 | 73 | @Override 74 | public void onFinish(ITestContext context) { 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/test/java/example/example/listeners/ReportListener.java: -------------------------------------------------------------------------------- 1 | package example.example.listeners; 2 | 3 | import org.testng.ITestContext; 4 | import org.testng.ITestListener; 5 | import org.testng.ITestResult; 6 | 7 | import com.relevantcodes.extentreports.LogStatus; 8 | 9 | import example.example.report.ExtentReportManager; 10 | import example.example.util.ReportUtil; 11 | 12 | /** 13 | * The listener interface for receiving report events. The class that is 14 | * interested in processing a report event implements this interface, and the 15 | * object created with that class is registered with a component using the 16 | * component's addReportListener method. When the report event 17 | * occurs, that object's appropriate method is invoked. 18 | * 19 | * @see ReportEvent 20 | */ 21 | public class ReportListener implements ITestListener { 22 | 23 | /** 24 | * Gets the test name. 25 | * 26 | * @param result the result 27 | * @return the test name 28 | */ 29 | public String getTestName(ITestResult result) { 30 | return result.getTestName() != null ? result.getTestName() 31 | : result.getMethod().getConstructorOrMethod().getName(); 32 | } 33 | 34 | /** 35 | * Gets the test description. 36 | * 37 | * @param result the result 38 | * @return the test description 39 | */ 40 | public String getTestDescription(ITestResult result) { 41 | return result.getMethod().getDescription() != null ? result.getMethod().getDescription() : getTestName(result); 42 | } 43 | 44 | @Override 45 | public void onTestStart(ITestResult result) { 46 | ExtentReportManager.startTest(getTestName(result), getTestDescription(result)); 47 | } 48 | 49 | @Override 50 | public void onTestSuccess(ITestResult result) { 51 | ReportUtil.addScreenShot(LogStatus.PASS, "Test Passed"); 52 | } 53 | 54 | @Override 55 | public void onTestFailure(ITestResult result) { 56 | Throwable t = result.getThrowable(); 57 | String cause = ""; 58 | if (t != null) 59 | cause = t.getMessage(); 60 | ReportUtil.addScreenShot(LogStatus.FAIL, "Test Failed : " + cause); 61 | } 62 | 63 | @Override 64 | public void onTestSkipped(ITestResult result) { 65 | } 66 | 67 | @Override 68 | public void onTestFailedButWithinSuccessPercentage(ITestResult result) { 69 | } 70 | 71 | @Override 72 | public void onStart(ITestContext context) { 73 | } 74 | 75 | @Override 76 | public void onFinish(ITestContext context) { 77 | ExtentReportManager.endCurrentTest(); 78 | ExtentReportManager.getExtentReports().flush(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/test/java/example/example/pages/BasePage.java: -------------------------------------------------------------------------------- 1 | package example.example.pages; 2 | 3 | import java.time.Duration; 4 | 5 | import org.openqa.selenium.NoSuchElementException; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebDriverException; 8 | import org.openqa.selenium.support.PageFactory; 9 | import org.openqa.selenium.support.ui.FluentWait; 10 | 11 | /** 12 | * The Class BasePage every Page should extend this class. 13 | * 14 | * @author Bharathish 15 | */ 16 | public class BasePage { 17 | 18 | /** The driver. */ 19 | protected WebDriver driver; 20 | 21 | /** The waiter. */ 22 | protected FluentWait waiter; 23 | 24 | /** 25 | * Instantiates a new base page. 26 | * 27 | * @param driver the driver 28 | */ 29 | public BasePage(WebDriver driver) { 30 | super(); 31 | this.driver = driver; 32 | PageFactory.initElements(driver, this); 33 | waiter = new FluentWait(driver).ignoring(NoSuchElementException.class, WebDriverException.class) 34 | .withTimeout(Duration.ofSeconds(10)).pollingEvery(Duration.ofSeconds(2)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/example/example/pages/FacebookLoginPage.java: -------------------------------------------------------------------------------- 1 | package example.example.pages; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | /** 8 | * The Class represents FacebookLoginPage. 9 | * 10 | * @author Bharathish 11 | */ 12 | public class FacebookLoginPage extends BasePage { 13 | 14 | /** The email input. */ 15 | @FindBy(id = "email") 16 | private WebElement emailInput; 17 | 18 | /** The pass. */ 19 | @FindBy(id = "pass") 20 | private WebElement pass; 21 | 22 | /** 23 | * Instantiates a new facebook login page. 24 | * 25 | * @param driver the driver 26 | */ 27 | public FacebookLoginPage(WebDriver driver) { 28 | super(driver); 29 | } 30 | 31 | /** 32 | * Enter email. 33 | * 34 | * @param email the email 35 | * @return the facebook login page 36 | */ 37 | public FacebookLoginPage enterEmail(String email) { 38 | emailInput.sendKeys(email); 39 | return this; 40 | } 41 | 42 | /** 43 | * Enter password. 44 | * 45 | * @param password the password 46 | * @return the facebook login page 47 | */ 48 | public FacebookLoginPage enterPassword(String password) { 49 | pass.sendKeys(password); 50 | return this; 51 | } 52 | 53 | /** 54 | * Click sign in. 55 | */ 56 | public void clickSignIn() { 57 | pass.submit(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/example/example/pages/GooglePage.java: -------------------------------------------------------------------------------- 1 | package example.example.pages; 2 | 3 | import org.openqa.selenium.Keys; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | 8 | /** 9 | * The Class represents GooglePage. 10 | * 11 | * @author Bharathish 12 | */ 13 | public class GooglePage extends BasePage { 14 | 15 | /** The searchinput. */ 16 | @FindBy(name = "q") 17 | private WebElement searchinput; 18 | 19 | /** 20 | * Instantiates a new google page. 21 | * 22 | * @param driver the driver 23 | */ 24 | public GooglePage(WebDriver driver) { 25 | super(driver); 26 | } 27 | 28 | /** 29 | * Searches the given text. 30 | * 31 | * @param key the key 32 | */ 33 | public void searchText(String key) { 34 | searchinput.sendKeys(key + Keys.ENTER); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/example/example/report/ExtentReportManager.java: -------------------------------------------------------------------------------- 1 | package example.example.report; 2 | 3 | import java.io.File; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import com.relevantcodes.extentreports.ExtentReports; 8 | import com.relevantcodes.extentreports.ExtentTest; 9 | 10 | import example.example.context.Constants; 11 | 12 | /** 13 | * The Class handles the report activities. 14 | * 15 | * @author Bharathish 16 | */ 17 | public class ExtentReportManager { 18 | 19 | /** The extent reports. */ 20 | private static ExtentReports extentReports; 21 | 22 | /** The map. */ 23 | private static Map map = new HashMap<>(); 24 | 25 | /** 26 | * Gets the extent reports. 27 | * 28 | * @return the extent reports 29 | */ 30 | public static ExtentReports getExtentReports() { 31 | if (extentReports == null) { 32 | extentReports = new ExtentReports(Constants.REPORT_DIRECTORY); 33 | extentReports.assignProject(Constants.PROJECT_NAME); 34 | extentReports.loadConfig(new File(Constants.EXTENT_CONFIG_PATH)); 35 | } 36 | return extentReports; 37 | } 38 | 39 | /** 40 | * Start test. 41 | * 42 | * @param testName the test name 43 | * @param desc the desc 44 | */ 45 | public synchronized static void startTest(String testName, String desc) { 46 | ExtentTest test = getExtentReports().startTest(testName, desc); 47 | map.put(Thread.currentThread().getId(), test); 48 | } 49 | 50 | /** 51 | * Gets the current test. 52 | * 53 | * @return the current test 54 | */ 55 | public synchronized static ExtentTest getCurrentTest() { 56 | return map.get(Thread.currentThread().getId()); 57 | } 58 | 59 | /** 60 | * End current test. 61 | */ 62 | public synchronized static void endCurrentTest() { 63 | getExtentReports().endTest(getCurrentTest()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/example/example/tests/BaseTest.java: -------------------------------------------------------------------------------- 1 | package example.example.tests; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | import org.openqa.selenium.chrome.ChromeOptions; 8 | import org.testng.ITestContext; 9 | import org.testng.annotations.AfterClass; 10 | import org.testng.annotations.AfterSuite; 11 | import org.testng.annotations.BeforeClass; 12 | import org.testng.annotations.BeforeSuite; 13 | import org.testng.annotations.Listeners; 14 | 15 | import example.example.context.WebDriverContext; 16 | import example.example.listeners.LogListener; 17 | import example.example.listeners.ReportListener; 18 | import example.example.util.LoggerUtil; 19 | import example.example.util.MailUtil; 20 | import example.example.util.TestProperties; 21 | import io.github.bonigarcia.wdm.WebDriverManager; 22 | 23 | /** 24 | * Every test class should extend this calss. 25 | * 26 | * @author Bharathish 27 | */ 28 | @Listeners({ ReportListener.class, LogListener.class }) 29 | public class BaseTest { 30 | 31 | /** The driver. */ 32 | protected WebDriver driver; 33 | 34 | /** 35 | * Global setup. 36 | */ 37 | @BeforeSuite(alwaysRun = true) 38 | public void globalSetup() { 39 | LoggerUtil.log("************************** Test Execution Started ************************************"); 40 | TestProperties.loadAllPropertie(); 41 | } 42 | 43 | /** 44 | * Wrap all up. 45 | * 46 | * @param context the context 47 | */ 48 | @AfterSuite(alwaysRun = true) 49 | public void wrapAllUp(ITestContext context) { 50 | int total = context.getAllTestMethods().length; 51 | int passed = context.getPassedTests().size(); 52 | int failed = context.getFailedTests().size(); 53 | int skipped = context.getSkippedTests().size(); 54 | LoggerUtil.log("Total number of testcases : " + total); 55 | LoggerUtil.log("Number of testcases Passed : " + passed); 56 | LoggerUtil.log("Number of testcases Failed : " + failed); 57 | LoggerUtil.log("Number of testcases Skipped : " + skipped); 58 | boolean mailSent = MailUtil.sendMail(total, passed, failed, skipped); 59 | LoggerUtil.log("Mail sent : " + mailSent); 60 | LoggerUtil.log("************************** Test Execution Finished ************************************"); 61 | } 62 | 63 | /** 64 | * Setup. 65 | */ 66 | @BeforeClass 67 | protected void setup() { 68 | // System.setProperty("webdriver.chrome.driver", Constants.CHROME_DRIVER_PATH); 69 | WebDriverManager.chromedriver().setup(); 70 | ChromeOptions ops = new ChromeOptions(); 71 | ops.addArguments("disable-infobars"); 72 | driver = new ChromeDriver(ops); 73 | driver.manage().window().maximize(); 74 | driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 75 | WebDriverContext.setDriver(driver); 76 | } 77 | 78 | /** 79 | * Wrap up. 80 | */ 81 | @AfterClass 82 | public void wrapUp() { 83 | if (driver != null) { 84 | driver.close(); 85 | driver.quit(); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/example/example/tests/FaceBookLoginTest.java: -------------------------------------------------------------------------------- 1 | package example.example.tests; 2 | 3 | import org.testng.Assert; 4 | import org.testng.annotations.Test; 5 | 6 | import example.example.factory.PageinstancesFactory; 7 | import example.example.pages.FacebookLoginPage; 8 | 9 | /** 10 | * The Class FaceBookLoginTest. 11 | * 12 | * @author Bharathish 13 | */ 14 | @Test(testName = "Facebook login test", description = "Facebook login test") 15 | public class FaceBookLoginTest extends BaseTest { 16 | 17 | @Test 18 | public void facebookLoginTest() { 19 | driver.get("https://www.facebook.com/"); 20 | FacebookLoginPage facebookLoginPage = PageinstancesFactory.getInstance(FacebookLoginPage.class); 21 | facebookLoginPage.enterEmail("abc").enterPassword("abc").clickSignIn(); 22 | Assert.assertTrue(false, "Login failed : Test failed"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/example/example/tests/GoogleSearchTest.java: -------------------------------------------------------------------------------- 1 | package example.example.tests; 2 | 3 | import org.testng.Assert; 4 | import org.testng.annotations.Test; 5 | 6 | import example.example.factory.PageinstancesFactory; 7 | import example.example.pages.GooglePage; 8 | 9 | /** 10 | * The Class GoogleSearchTest. 11 | * 12 | * @author Bharathish 13 | */ 14 | @Test(testName = "Google search test", description = "Test description") 15 | public class GoogleSearchTest extends BaseTest { 16 | 17 | /** 18 | * Google search test. 19 | */ 20 | @Test 21 | public void googleSearchTest() { 22 | driver.get("https://www.google.co.in/"); 23 | GooglePage googlePage = PageinstancesFactory.getInstance(GooglePage.class); 24 | googlePage.searchText("abc"); 25 | Assert.assertTrue(driver.getTitle().contains("abc"), "Title doesn't contain abc : Test Failed"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/example/example/util/LoggerUtil.java: -------------------------------------------------------------------------------- 1 | package example.example.util; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import example.example.listeners.LogListener; 6 | 7 | /** 8 | * The Class has all Logging related utilities. 9 | * 10 | * @author Bharathish 11 | */ 12 | public class LoggerUtil { 13 | 14 | /** The logger. */ 15 | private static Logger logger = Logger.getLogger(LogListener.class); 16 | 17 | /** 18 | * Log. 19 | * 20 | * @param message the message 21 | */ 22 | public static void log(String message) { 23 | logger.info(message); 24 | } 25 | 26 | /** 27 | * Gets the logger. 28 | * 29 | * @return the logger 30 | */ 31 | public static Logger getLogger() { 32 | return logger; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/example/example/util/MailUtil.java: -------------------------------------------------------------------------------- 1 | package example.example.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | import java.util.Date; 7 | import java.util.List; 8 | 9 | import javax.mail.Message.RecipientType; 10 | 11 | import org.simplejavamail.email.Email; 12 | import org.simplejavamail.email.EmailBuilder; 13 | import org.simplejavamail.email.Recipient; 14 | import org.simplejavamail.mailer.Mailer; 15 | import org.simplejavamail.mailer.MailerBuilder; 16 | import org.simplejavamail.mailer.config.TransportStrategy; 17 | 18 | /** 19 | * The Class is responsible for Mailing. 20 | * 21 | * @author Bharathish 22 | */ 23 | public class MailUtil { 24 | 25 | /** 26 | * Send mail. 27 | * 28 | * @param total the total 29 | * @param passed the passed 30 | * @param failed the failed 31 | * @param skipped the skipped 32 | * @return true, if successful 33 | */ 34 | @SuppressWarnings("unused") 35 | public static boolean sendMail(int total, int passed, int failed, int skipped) { 36 | 37 | boolean sendMail = Boolean.parseBoolean(TestProperties.getProperty("mail.sendmail")); 38 | 39 | if (sendMail) { 40 | try { 41 | String[] tos = TestProperties.getProperty("mail.to").split(","); 42 | String from = TestProperties.getProperty("mail.from"); 43 | String mailHost = TestProperties.getProperty("mail.host"); 44 | int port = Integer.parseInt(TestProperties.getProperty("mail.port")); 45 | String username = TestProperties.getProperty("mail.user"); 46 | String pwd = TestProperties.getProperty("mail.password"); 47 | // String proxyServer = TestProperties.getProperty("mail.proxy.server"); 48 | // int proxyPort = Integer.parseInt(TestProperties.getProperty("mail.proxy.port")); 49 | // String proxyUsername = TestProperties.getProperty("mail.proxy.user"); 50 | // String proxyPassword = TestProperties.getProperty("mail.proxy.password"); 51 | String mailSubject = TestProperties.getProperty("mail.subject"); 52 | List recipients = new ArrayList<>(); 53 | Arrays.asList(tos).forEach(to -> { 54 | try { 55 | recipients.add(new Recipient("", to, RecipientType.TO)); 56 | } catch (Exception e) { 57 | LoggerUtil.log("Mail id is not correct : " + to); 58 | } 59 | }); 60 | 61 | /* 62 | * Enter smtp host, port, username and password in smtpserver details, If you 63 | * are running tests behind proxy, uncomment and enter proxy details 64 | */ 65 | Mailer mailer = MailerBuilder.withSMTPServer(mailHost, port, username, pwd) 66 | // .withProxy(proxyServer, proxyPort, proxyUsername, proxyPassword).clearEmailAddressCriteria() 67 | .withProperty("mail.smtp.sendpartial", "true").withProperty("mail.smtp.auth", "true") 68 | .withProperty("mail.smtp.starttls.enable", "true") 69 | .withTransportStrategy(TransportStrategy.SMTP_TLS).buildMailer(); 70 | 71 | Email email = EmailBuilder.startingBlank().from("Automation Execution", from).withRecipients(recipients) 72 | .withSubject(mailSubject + " | " + new SimpleDateFormat("MM-dd-yyyy").format(new Date())) 73 | .withHTMLText(getMailBody(total, passed, failed, skipped)).buildEmail(); 74 | 75 | mailer.sendMail(email); 76 | return true; 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | LoggerUtil.getLogger().fatal("Could not send mail : " + e.getMessage()); 80 | return false; 81 | } 82 | } else { 83 | LoggerUtil.log("Mail sending toggel is set to false"); 84 | return false; 85 | } 86 | } 87 | 88 | /** 89 | * Gets the mail body. 90 | * 91 | * @param total the total 92 | * @param passed the passed 93 | * @param failed the failed 94 | * @param skipped the skipped 95 | * @return the mail body 96 | */ 97 | private static String getMailBody(int total, int passed, int failed, int skipped) { 98 | return "\r\n" + "\r\n" + "\r\n" + "

Automation Execution report...

\r\n" 99 | + "\r\n" + " \r\n" 100 | + " \r\n" + " \r\n" 101 | + " \r\n" + " \r\n" 102 | + " \r\n" + " \r\n" + " \r\n" + " \r\n" 103 | + " \r\n" + " \r\n" + " \r\n" 104 | + "
TotalPassedFailedSkipped
" + total + "" + passed + "" + failed + "" + skipped + "
\r\n" + "\r\n" + "\r\n" + ""; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/test/java/example/example/util/ReportUtil.java: -------------------------------------------------------------------------------- 1 | package example.example.util; 2 | 3 | import org.openqa.selenium.OutputType; 4 | import org.openqa.selenium.TakesScreenshot; 5 | 6 | import com.relevantcodes.extentreports.LogStatus; 7 | 8 | import example.example.context.WebDriverContext; 9 | import example.example.report.ExtentReportManager; 10 | 11 | /** 12 | * The Class is responsible for Reporting 13 | * 14 | * @author Bharathish 15 | */ 16 | public class ReportUtil { 17 | 18 | /** 19 | * Adds the screen shot. 20 | * 21 | * @param message the message 22 | */ 23 | public static void addScreenShot(String message) { 24 | String base64Image = "data:image/png;base64," 25 | + ((TakesScreenshot) WebDriverContext.getDriver()).getScreenshotAs(OutputType.BASE64); 26 | ExtentReportManager.getCurrentTest().log(LogStatus.INFO, message, 27 | ExtentReportManager.getCurrentTest().addBase64ScreenShot(base64Image)); 28 | } 29 | 30 | /** 31 | * Adds the screen shot. 32 | * 33 | * @param status the status 34 | * @param message the message 35 | */ 36 | public static void addScreenShot(LogStatus status, String message) { 37 | String base64Image = "data:image/png;base64," 38 | + ((TakesScreenshot) WebDriverContext.getDriver()).getScreenshotAs(OutputType.BASE64); 39 | ExtentReportManager.getCurrentTest().log(status, message, 40 | ExtentReportManager.getCurrentTest().addBase64ScreenShot(base64Image)); 41 | } 42 | 43 | public static void logMessage(String message, String details) { 44 | ExtentReportManager.getCurrentTest().log(LogStatus.INFO, message, details); 45 | } 46 | 47 | public static void logMessage(LogStatus status, String message, String details) { 48 | ExtentReportManager.getCurrentTest().log(status, message, details); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/example/example/util/TestProperties.java: -------------------------------------------------------------------------------- 1 | package example.example.util; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.Properties; 6 | 7 | import example.example.context.Constants; 8 | 9 | /** 10 | * The Class has all TestProperties (All properties mentioned in test.properties file). 11 | * 12 | * @author Bharathish 13 | */ 14 | public class TestProperties { 15 | 16 | /** The Constant props. */ 17 | private static final Properties props = new Properties(); 18 | 19 | /** 20 | * Load all propertie. 21 | */ 22 | public static void loadAllPropertie() { 23 | try { 24 | FileInputStream Locator; 25 | Locator = new FileInputStream(Constants.PROPERTY_FILE_PATH); 26 | props.load(Locator); 27 | } catch (IOException e) { 28 | LoggerUtil.getLogger().fatal("Could not load properties : " + e.getMessage()); 29 | } 30 | } 31 | 32 | /** 33 | * Gets the property. 34 | * 35 | * @param key the key 36 | * @return the property 37 | */ 38 | public static String getProperty(String key) { 39 | return props.getProperty(key); 40 | } 41 | 42 | /** 43 | * Put property. 44 | * 45 | * @param key the key 46 | * @param value the value 47 | */ 48 | public static void putProperty(String key, String value) { 49 | props.put(key, value); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/resources/config/extent-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | standard 7 | 8 | 9 | 10 | UTF-8 11 | 12 | 13 | 14 | https 15 | 16 | 17 | Extent 18 | 19 | 20 | Automation Report 21 | 22 | 23 | 24 | bottom 25 | 26 | 27 | 28 | span").innerHTML="Your-Application"; 33 | }, 5000); 34 | }); 35 | ]]> 36 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/test/resources/config/test.properties: -------------------------------------------------------------------------------- 1 | ### All global properties you can place here ### 2 | 3 | ## Mail properties ## 4 | # If you are using gmail, the you have to do 2 things 5 | # 1. Go to https://www.google.com/settings/security/lesssecureapps, then allow less secure apps 6 | # 2. Go to https://accounts.google.com/b/0/DisplayUnlockCaptcha, and continue 7 | # for more info refer https://stackoverflow.com/questions/25341198/javax-mail-authenticationfailedexception-is-thrown-while-sending-email-in-java 8 | # If you are under proxy then uncomment proxy properties here and in MailUtil calss. 9 | mail.sendmail=false 10 | mail.host=smtp.gmail.com 11 | mail.port=587 12 | mail.user=yourmail@gmail.com 13 | mail.password=your_password 14 | #mail.proxy.server= 15 | #mail.proxy.port= 16 | #mail.proxy.user= 17 | #mail.proxy.password= 18 | mail.subject=Automation Report 19 | mail.from=yourmail@gmail.com 20 | mail.to=toaddress1@gmail.com,toAddress2@gmail.com -------------------------------------------------------------------------------- /src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/suites/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | --------------------------------------------------------------------------------