├── CourseLandingPage.png ├── README.md ├── pom.xml ├── src └── test │ ├── java │ └── org │ │ └── selenium │ │ └── pom │ │ ├── api │ │ └── actions │ │ │ ├── CartApi.java │ │ │ ├── DummyClass.java │ │ │ └── SignUpApi.java │ │ ├── base │ │ ├── BasePage.java │ │ └── BaseTest.java │ │ ├── constants │ │ ├── DriverType.java │ │ └── EnvType.java │ │ ├── dataproviders │ │ └── MyDataProvider.java │ │ ├── factory │ │ ├── ChromeDriverManager.java │ │ ├── DriverManager.java │ │ ├── DriverManagerFactory.java │ │ ├── DriverManagerOriginal.java │ │ ├── FirefoxDriverManager.java │ │ └── abstractFactory │ │ │ ├── ChromeDriverManagerAbstract.java │ │ │ ├── DriverManagerAbstract.java │ │ │ ├── DriverManagerFactoryAbstract.java │ │ │ └── FirefoxDriverManagerAbstract.java │ │ ├── objects │ │ ├── BillingAddress.java │ │ ├── Product.java │ │ └── User.java │ │ ├── pages │ │ ├── CartPage.java │ │ ├── CheckoutPage.java │ │ ├── HomePage.java │ │ ├── StorePage.java │ │ └── components │ │ │ ├── MyHeader.java │ │ │ └── ProductThumbnail.java │ │ ├── tests │ │ ├── AddToCartTest.java │ │ ├── CheckoutTest.java │ │ ├── LoginTest.java │ │ ├── MyFirstTestCase.java │ │ ├── NavigationTest.java │ │ └── SearchTest.java │ │ └── utils │ │ ├── ConfigLoader.java │ │ ├── CookieUtils.java │ │ ├── FakerUtils.java │ │ ├── JacksonUtils.java │ │ └── PropertyUtils.java │ └── resources │ ├── myBillingAddress.json │ ├── prod_config.properties │ ├── products.json │ └── stg_config.properties └── testng.xml /CourseLandingPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omprakashchavan01/selenium-pageobjectmodel/52760712fa7d2109d4ba296b3607f18c546c31df/CourseLandingPage.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # selenium-pageobjectmodel 2 | **Page Object Model design using Java + TestNG (Or Junit) + Maven. Supports Parallel. Uses APIs to setup test data and application state. Follows industry best practices.** 3 | 4 | **Step by step instructions to build this framework from scratch, learn automation best practices and integrate with Jenkins CI is in this Udemy course. 5 | Enroll today at the minimal rate of INR 549/ $14.99. 6 | Link with coupon code: https://www.udemy.com/course/selenium-java-test-framework/?couponCode=APR2024** 7 | 8 | ![Udemy_Landing_Page](/CourseLandingPage.png) 9 | 10 | Technologies/Tools used in building the framework 11 | ================================================= 12 | - Selenium WebDriver 13 | - Java 14 | - Maven 15 | - TestNG 16 | - JUnit 17 | - Rest Assured 18 | - Jackson Data bind 19 | - Allure Reports 20 | - IntelliJ 21 | - GitHub 22 | - Jenkins 23 | 24 | What you'll learn? 25 | ================== 26 | - Develop Page Object Model frameworks from scratch for any Live website 27 | - 50+ Industry best practices to follow for framework development 28 | - Learn to develop Readable, Maintainable and Scalable frameworks from scratch 29 | - Bad practices to avoid during framework development 30 | - Easily integrate APIs using REST Assured to skip login through UI [Selenium recommendation] 31 | - Use APIs to setup test data [Selenium Recommendation] 32 | - Learn how to easily write Atomic and Independent tests [Selenium Recommendation] 33 | - Learn how to setup application state for tests [Selenium Recommendation] 34 | - Learn to implement Parallel execution using TestNG, Maven and JUnit 35 | - How to easily configure and drive automation frameworks using TestNG, JUnit and Maven 36 | - Factory Design Pattern - Using Interface and Abstract class 37 | - Singleton Design Pattern 38 | - Learn how to follow the Single Responsibility Principle (SRP) 39 | - Learn how to follow the Do Not Repeat Yourself (DRY) principle 40 | - When and how to use OOP concepts in frameworks [Inheritance, Interface, Encapsulation, Polymorphism] 41 | - Learn how to reuse Page Objects using Composition 42 | - Learn about Fluent Interface and Builder design in Page Objects 43 | - How to effectively use TestNG Data providers to drive test variations 44 | - How to go about efficiently supporting multiple browsers and Environments 45 | - Automated WebDriver management 46 | - Learn Allure Reporting and generate feature rich reports 47 | - Learn how to integrate the framework with GitHub 48 | - Learn how to auto-trigger automation from Jenkins using GitHub Web Hooks, SCM Polling and Build Frequency 49 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | MasterSeleniumFramework 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 21 13 | 21 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-surefire-plugin 22 | 3.2.2 23 | 24 | methods 25 | 6 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.seleniumhq.selenium 38 | selenium-java 39 | 4.15.0 40 | 41 | 42 | 43 | org.testng 44 | testng 45 | 7.8.0 46 | test 47 | 48 | 49 | 50 | com.fasterxml.jackson.core 51 | jackson-databind 52 | 2.16.0 53 | 54 | 55 | 56 | io.github.bonigarcia 57 | webdrivermanager 58 | 5.6.2 59 | 60 | 61 | 62 | io.rest-assured 63 | rest-assured 64 | 5.3.2 65 | test 66 | 67 | 68 | 69 | org.jsoup 70 | jsoup 71 | 1.16.2 72 | 73 | 74 | 75 | com.github.javafaker 76 | javafaker 77 | 1.0.2 78 | 79 | 80 | 81 | ru.yandex.qatools.ashot 82 | ashot 83 | 1.5.4 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/api/actions/CartApi.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.api.actions; 2 | 3 | import io.restassured.http.Cookies; 4 | import io.restassured.http.Header; 5 | import io.restassured.http.Headers; 6 | import io.restassured.response.Response; 7 | import org.selenium.pom.utils.ConfigLoader; 8 | 9 | import java.util.HashMap; 10 | 11 | import static io.restassured.RestAssured.given; 12 | 13 | public class CartApi { 14 | private Cookies cookies; 15 | 16 | public CartApi(){} 17 | 18 | public CartApi(Cookies cookies){ 19 | this.cookies = cookies; 20 | } 21 | 22 | public Cookies getCookies(){ 23 | return cookies; 24 | } 25 | 26 | public Response addToCart(int productId, int quantity){ 27 | Header header = new Header("content-type", "application/x-www-form-urlencoded"); 28 | Headers headers = new Headers(header); 29 | HashMap formParams = new HashMap<>(); 30 | formParams.put("product_sku", ""); 31 | formParams.put("product_id", productId); 32 | formParams.put("quantity", quantity); 33 | 34 | if(cookies == null){ 35 | cookies = new Cookies(); 36 | } 37 | 38 | Response response = given(). 39 | baseUri(ConfigLoader.getInstance().getBaseUrl()). 40 | headers(headers). 41 | formParams(formParams). 42 | cookies(cookies). 43 | log().all(). 44 | when(). 45 | post("/?wc-ajax=add_to_cart"). 46 | then(). 47 | log().all(). 48 | extract(). 49 | response(); 50 | if(response.getStatusCode() != 200){ 51 | throw new RuntimeException("Failed to add product" + productId + " to the cart" + 52 | ", HTTP Status Code: " + response.getStatusCode()); 53 | } 54 | this.cookies = response.getDetailedCookies(); 55 | return response; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/api/actions/DummyClass.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.api.actions; 2 | 3 | import org.selenium.pom.objects.User; 4 | import org.selenium.pom.utils.FakerUtils; 5 | 6 | public class DummyClass { 7 | 8 | public static void main(String[] args){ 9 | String username = "demouser" + new FakerUtils().generateRandomNumber(); 10 | User user = new User(). 11 | setUsername(username). 12 | setPassword("demopwd"). 13 | setEmail(username + "@askomdch.com"); 14 | SignUpApi signUpApi = new SignUpApi(); 15 | signUpApi.register(user); 16 | System.out.println("REGISTER COOKIES: " + signUpApi.getCookies()); 17 | CartApi cartApi = new CartApi(signUpApi.getCookies()); 18 | cartApi.addToCart(1215, 1); 19 | System.out.println("CART COOKIES: " + cartApi.getCookies()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/api/actions/SignUpApi.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.api.actions; 2 | 3 | import io.restassured.http.Cookies; 4 | import io.restassured.http.Header; 5 | import io.restassured.http.Headers; 6 | import io.restassured.response.Response; 7 | import org.jsoup.Jsoup; 8 | import org.jsoup.nodes.Document; 9 | import org.jsoup.nodes.Element; 10 | import org.selenium.pom.objects.User; 11 | import org.selenium.pom.utils.ConfigLoader; 12 | 13 | import java.util.HashMap; 14 | 15 | import static io.restassured.RestAssured.given; 16 | 17 | public class SignUpApi { 18 | private Cookies cookies; 19 | 20 | public Cookies getCookies(){ 21 | return cookies; 22 | } 23 | 24 | private String fetchRegisterNonceValueUsingGroovy(){ 25 | Response response = getAccount(); 26 | return response.htmlPath().getString("**.findAll { it.@name == 'woocommerce-register-nonce' }.@value"); 27 | } 28 | 29 | private String fetchRegisterNonceValueUsingJsoup(){ 30 | Response response = getAccount(); 31 | Document doc = Jsoup.parse(response.body().prettyPrint()); 32 | Element element = doc.selectFirst("#woocommerce-register-nonce"); 33 | return element.attr("value"); 34 | } 35 | 36 | private Response getAccount(){ 37 | Cookies cookies = new Cookies(); 38 | Response response = given(). 39 | baseUri(ConfigLoader.getInstance().getBaseUrl()). 40 | cookies(cookies). 41 | log().all(). 42 | when(). 43 | get("/account"). 44 | then(). 45 | log().all(). 46 | extract(). 47 | response(); 48 | if(response.getStatusCode() != 200){ 49 | throw new RuntimeException("Failed to fetch the account, HTTP Status Code: " + response.getStatusCode()); 50 | } 51 | return response; 52 | } 53 | 54 | public Response register(User user){ 55 | Cookies cookies = new Cookies(); 56 | Header header = new Header("content-type", "application/x-www-form-urlencoded"); 57 | Headers headers = new Headers(header); 58 | HashMap formParams = new HashMap<>(); 59 | formParams.put("username", user.getUsername()); 60 | formParams.put("email", user.getEmail()); 61 | formParams.put("password", user.getPassword()); 62 | formParams.put("woocommerce-register-nonce", fetchRegisterNonceValueUsingJsoup()); 63 | formParams.put("register", "Register"); 64 | 65 | Response response = given(). 66 | baseUri(ConfigLoader.getInstance().getBaseUrl()). 67 | headers(headers). 68 | formParams(formParams). 69 | cookies(cookies). 70 | log().all(). 71 | when(). 72 | post("/account"). 73 | then(). 74 | log().all(). 75 | extract(). 76 | response(); 77 | if(response.getStatusCode() != 302){ 78 | throw new RuntimeException("Failed to register the account, HTTP Status Code: " + response.getStatusCode()); 79 | } 80 | this.cookies = response.getDetailedCookies(); 81 | return response; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/base/BasePage.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.base; 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.ui.ExpectedConditions; 7 | import org.openqa.selenium.support.ui.WebDriverWait; 8 | import org.selenium.pom.utils.ConfigLoader; 9 | 10 | import java.time.Duration; 11 | import java.util.List; 12 | 13 | public class BasePage { 14 | protected WebDriver driver; 15 | protected WebDriverWait wait; 16 | 17 | public BasePage(WebDriver driver){ 18 | this.driver = driver; 19 | wait = new WebDriverWait(driver, Duration.ofSeconds(30)); 20 | } 21 | 22 | public void load(String endPoint){ 23 | driver.get(ConfigLoader.getInstance().getBaseUrl() + endPoint); 24 | } 25 | 26 | public void waitForOverlaysToDisappear(By overlay){ 27 | List overlays = driver.findElements(overlay); 28 | System.out.println("OVERLAY SIZE" + overlays.size()); 29 | if(overlays.size() > 0){ 30 | wait.until(ExpectedConditions.invisibilityOfAllElements(overlays)); 31 | System.out.println("OVERLAYS INVISIBLE"); 32 | } else{ 33 | System.out.println("OVERLAY NOT FOUND"); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/base/BaseTest.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.base; 2 | 3 | import io.restassured.http.Cookies; 4 | import org.apache.commons.io.FileUtils; 5 | import org.openqa.selenium.Cookie; 6 | import org.openqa.selenium.OutputType; 7 | import org.openqa.selenium.TakesScreenshot; 8 | import org.openqa.selenium.WebDriver; 9 | import org.selenium.pom.constants.DriverType; 10 | import org.selenium.pom.factory.abstractFactory.DriverManagerAbstract; 11 | import org.selenium.pom.factory.abstractFactory.DriverManagerFactoryAbstract; 12 | import org.selenium.pom.utils.CookieUtils; 13 | import org.testng.ITestResult; 14 | import org.testng.annotations.AfterMethod; 15 | import org.testng.annotations.BeforeMethod; 16 | import org.testng.annotations.Optional; 17 | import org.testng.annotations.Parameters; 18 | import ru.yandex.qatools.ashot.AShot; 19 | import ru.yandex.qatools.ashot.Screenshot; 20 | import ru.yandex.qatools.ashot.shooting.ShootingStrategies; 21 | 22 | import javax.imageio.ImageIO; 23 | import java.io.File; 24 | import java.io.IOException; 25 | import java.util.List; 26 | 27 | public class BaseTest { 28 | private final ThreadLocal driverManager = new ThreadLocal<>(); 29 | private final ThreadLocal driver = new ThreadLocal<>(); 30 | 31 | private void setDriverManager(DriverManagerAbstract driverManager){ 32 | this.driverManager.set(driverManager); 33 | } 34 | 35 | protected DriverManagerAbstract getDriverManager(){ 36 | return this.driverManager.get(); 37 | } 38 | 39 | private void setDriver(WebDriver driver){ 40 | this.driver.set(driver); 41 | } 42 | 43 | protected WebDriver getDriver(){ 44 | return this.driver.get(); 45 | } 46 | 47 | @Parameters("browser") 48 | @BeforeMethod 49 | public synchronized void startDriver(@Optional String browser){ 50 | browser = System.getProperty("browser", browser); 51 | // if(browser == null) browser = "CHROME"; 52 | // setDriver(new DriverManagerOriginal().initializeDriver(browser)); 53 | // setDriver(DriverManagerFactory.getManager(DriverType.valueOf(browser)).createDriver()); 54 | setDriverManager(DriverManagerFactoryAbstract. 55 | getManager(DriverType.valueOf(browser))); 56 | setDriver(getDriverManager().getDriver()); 57 | System.out.println("CURRENT THREAD: " + Thread.currentThread().threadId() + ", " + 58 | "DRIVER = " + getDriver()); 59 | } 60 | 61 | @Parameters("browser") 62 | @AfterMethod 63 | public synchronized void quitDriver(@Optional String browser, ITestResult result) throws InterruptedException, IOException { 64 | Thread.sleep(300); 65 | System.out.println("CURRENT THREAD: " + Thread.currentThread().threadId() + ", " + 66 | "DRIVER = " + getDriver()); 67 | // getDriver().quit(); 68 | if(result.getStatus() == ITestResult.FAILURE){ 69 | File destFile = new File("scr" + File.separator + browser + File.separator + 70 | result.getTestClass().getRealClass().getSimpleName() + "_" + 71 | result.getMethod().getMethodName() + ".png"); 72 | // takeScreenshot(destFile); 73 | takeScreenshotUsingAShot(destFile); 74 | } 75 | getDriverManager().getDriver().quit(); 76 | } 77 | 78 | public void injectCookiesToBrowser(Cookies cookies){ 79 | List seleniumCookies = new CookieUtils().convertRestAssuredCookiesToSeleniumCookies(cookies); 80 | for(Cookie cookie: seleniumCookies){ 81 | System.out.println(cookie.toString()); 82 | getDriver().manage().addCookie(cookie); 83 | } 84 | } 85 | 86 | private void takeScreenshot(File destFile) throws IOException { 87 | TakesScreenshot takesScreenshot = (TakesScreenshot) getDriver(); 88 | File srcFile = takesScreenshot.getScreenshotAs(OutputType.FILE); 89 | FileUtils.copyFile(srcFile, destFile); 90 | } 91 | 92 | private void takeScreenshotUsingAShot(File destFile){ 93 | Screenshot screenshot = new AShot() 94 | .shootingStrategy(ShootingStrategies.viewportPasting(100)) 95 | .takeScreenshot(getDriver()); 96 | try{ 97 | ImageIO.write(screenshot.getImage(), "PNG", destFile); 98 | }catch (IOException e){ 99 | e.printStackTrace(); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/constants/DriverType.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.constants; 2 | 3 | public enum DriverType { 4 | CHROME, 5 | FIREFOX 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/constants/EnvType.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.constants; 2 | 3 | public enum EnvType { 4 | PRODUCTION, 5 | STAGE 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/dataproviders/MyDataProvider.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.dataproviders; 2 | 3 | import org.selenium.pom.objects.Product; 4 | import org.selenium.pom.utils.JacksonUtils; 5 | import org.testng.annotations.DataProvider; 6 | 7 | import java.io.IOException; 8 | 9 | public class MyDataProvider { 10 | 11 | @DataProvider(name = "getFeaturedProducts", parallel = false) 12 | public Object[] getFeaturedProducts() throws IOException { 13 | return JacksonUtils.deserializeJson("products.json", Product[].class); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/ChromeDriverManager.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory; 2 | 3 | import io.github.bonigarcia.wdm.WebDriverManager; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.chrome.ChromeDriver; 6 | 7 | public class ChromeDriverManager implements DriverManager{ 8 | 9 | @Override 10 | public WebDriver createDriver() { 11 | WebDriverManager.chromedriver().cachePath("Drivers").setup(); 12 | WebDriver driver = new ChromeDriver(); 13 | driver.manage().window().maximize(); 14 | return driver; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/DriverManager.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | 5 | public interface DriverManager { 6 | WebDriver createDriver(); 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/DriverManagerFactory.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory; 2 | 3 | import org.selenium.pom.constants.DriverType; 4 | 5 | public class DriverManagerFactory { 6 | 7 | public static DriverManager getManager(DriverType driverType){ 8 | switch (driverType){ 9 | case CHROME -> { 10 | return new ChromeDriverManager(); 11 | } 12 | case FIREFOX -> { 13 | return new FirefoxDriverManager(); 14 | } 15 | default -> throw new IllegalStateException("Unexpected value: " + driverType); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/DriverManagerOriginal.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory; 2 | 3 | import io.github.bonigarcia.wdm.WebDriverManager; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.chrome.ChromeDriver; 6 | import org.openqa.selenium.firefox.FirefoxDriver; 7 | import org.selenium.pom.constants.DriverType; 8 | 9 | public class DriverManagerOriginal { 10 | 11 | public WebDriver initializeDriver(String browser){ 12 | WebDriver driver; 13 | switch (DriverType.valueOf(browser)) { 14 | case CHROME -> { 15 | WebDriverManager.chromedriver().cachePath("Drivers").setup(); 16 | driver = new ChromeDriver(); 17 | } 18 | case FIREFOX -> { 19 | WebDriverManager.firefoxdriver().cachePath("Drivers").setup(); 20 | driver = new FirefoxDriver(); 21 | } 22 | default -> throw new IllegalStateException("Invalid browser name: " + browser); 23 | } 24 | driver.manage().window().maximize(); 25 | // driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(15)); 26 | return driver; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/FirefoxDriverManager.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory; 2 | 3 | import io.github.bonigarcia.wdm.WebDriverManager; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.firefox.FirefoxDriver; 6 | 7 | public class FirefoxDriverManager implements DriverManager{ 8 | 9 | @Override 10 | public WebDriver createDriver() { 11 | WebDriverManager.firefoxdriver().cachePath("Drivers").setup(); 12 | WebDriver driver = new FirefoxDriver(); 13 | driver.manage().window().maximize(); 14 | return driver; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/abstractFactory/ChromeDriverManagerAbstract.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory.abstractFactory; 2 | 3 | import io.github.bonigarcia.wdm.WebDriverManager; 4 | import org.openqa.selenium.chrome.ChromeDriver; 5 | 6 | public class ChromeDriverManagerAbstract extends DriverManagerAbstract { 7 | 8 | @Override 9 | protected void startDriver() { 10 | WebDriverManager.chromedriver().cachePath("Drivers").setup(); 11 | driver = new ChromeDriver(); 12 | driver.manage().window().maximize(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/abstractFactory/DriverManagerAbstract.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory.abstractFactory; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | 5 | public abstract class DriverManagerAbstract { 6 | protected WebDriver driver; 7 | 8 | protected abstract void startDriver(); 9 | 10 | public void quitDriver(){ 11 | if(driver != null){ 12 | driver.quit(); 13 | driver = null; 14 | } 15 | } 16 | 17 | public WebDriver getDriver(){ 18 | if(driver == null){ 19 | startDriver(); 20 | } 21 | return driver; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/abstractFactory/DriverManagerFactoryAbstract.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory.abstractFactory; 2 | 3 | import org.selenium.pom.constants.DriverType; 4 | 5 | public class DriverManagerFactoryAbstract { 6 | 7 | public static DriverManagerAbstract getManager(DriverType driverType){ 8 | switch (driverType){ 9 | case CHROME -> { 10 | return new ChromeDriverManagerAbstract(); 11 | } 12 | case FIREFOX -> { 13 | return new FirefoxDriverManagerAbstract(); 14 | } 15 | default -> throw new IllegalStateException("Unexpected value: " + driverType); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/factory/abstractFactory/FirefoxDriverManagerAbstract.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.factory.abstractFactory; 2 | 3 | import io.github.bonigarcia.wdm.WebDriverManager; 4 | import org.openqa.selenium.firefox.FirefoxDriver; 5 | 6 | public class FirefoxDriverManagerAbstract extends DriverManagerAbstract { 7 | 8 | @Override 9 | protected void startDriver() { 10 | WebDriverManager.firefoxdriver().cachePath("Drivers").setup(); 11 | driver = new FirefoxDriver(); 12 | driver.manage().window().maximize(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/objects/BillingAddress.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.objects; 2 | 3 | public class BillingAddress { 4 | private String firstName; 5 | private String lastName; 6 | private String addressLineOne; 7 | private String city; 8 | private String postalCode; 9 | private String email; 10 | private String country; 11 | private String state; 12 | 13 | public String getCountry() { 14 | return country; 15 | } 16 | 17 | public void setCountry(String country) { 18 | this.country = country; 19 | } 20 | 21 | public String getState() { 22 | return state; 23 | } 24 | 25 | public void setState(String state) { 26 | this.state = state; 27 | } 28 | 29 | public BillingAddress(){} 30 | 31 | public BillingAddress(String firstName, String lastName, String addressLineOne, String city, 32 | String postalCode, String email){ 33 | this.firstName = firstName; 34 | this.lastName = lastName; 35 | this.addressLineOne = addressLineOne; 36 | this.city = city; 37 | this.postalCode = postalCode; 38 | this.email = email; 39 | } 40 | 41 | public String getFirstName() { 42 | return firstName; 43 | } 44 | 45 | public BillingAddress setFirstName(String firstName) { 46 | this.firstName = firstName; 47 | return this; 48 | } 49 | 50 | public String getLastName() { 51 | return lastName; 52 | } 53 | 54 | public BillingAddress setLastName(String lastName) { 55 | this.lastName = lastName; 56 | return this; 57 | } 58 | 59 | public String getAddressLineOne() { 60 | return addressLineOne; 61 | } 62 | 63 | public BillingAddress setAddressLineOne(String addressLineOne) { 64 | this.addressLineOne = addressLineOne; 65 | return this; 66 | } 67 | 68 | public String getCity() { 69 | return city; 70 | } 71 | 72 | public BillingAddress setCity(String city) { 73 | this.city = city; 74 | return this; 75 | } 76 | 77 | public String getPostalCode() { 78 | return postalCode; 79 | } 80 | 81 | public BillingAddress setPostalCode(String postalCode) { 82 | this.postalCode = postalCode; 83 | return this; 84 | } 85 | 86 | public String getEmail() { 87 | return email; 88 | } 89 | 90 | public BillingAddress setEmail(String email) { 91 | this.email = email; 92 | return this; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/objects/Product.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.objects; 2 | 3 | import org.selenium.pom.utils.JacksonUtils; 4 | 5 | import java.io.IOException; 6 | 7 | public class Product { 8 | private int id; 9 | private String name; 10 | 11 | public Product(){} 12 | 13 | public Product(int id) throws IOException { 14 | Product[] products = JacksonUtils.deserializeJson("products.json", Product[].class); 15 | for(Product product: products){ 16 | if(product.getId() == id){ 17 | this.id = id; 18 | this.name = product.getName(); 19 | } 20 | } 21 | } 22 | 23 | public int getId() { 24 | return id; 25 | } 26 | 27 | public void setId(int id) { 28 | this.id = id; 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public void setName(String name) { 36 | this.name = name; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/objects/User.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.objects; 2 | 3 | public class User { 4 | private String username; 5 | private String password; 6 | private String email; 7 | 8 | public String getEmail() { 9 | return email; 10 | } 11 | 12 | public User setEmail(String email) { 13 | this.email = email; 14 | return this; 15 | } 16 | 17 | public User(){} 18 | 19 | public User(String username, String password){ 20 | this.username = username; 21 | this.password = password; 22 | } 23 | 24 | public User(String username, String password, String email){ 25 | this.username = username; 26 | this.password = password; 27 | this.email = email; 28 | } 29 | 30 | public String getUsername() { 31 | return username; 32 | } 33 | 34 | public User setUsername(String username) { 35 | this.username = username; 36 | return this; 37 | } 38 | 39 | public String getPassword() { 40 | return password; 41 | } 42 | 43 | public User setPassword(String password) { 44 | this.password = password; 45 | return this; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/pages/CartPage.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.pages; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.CacheLookup; 6 | import org.openqa.selenium.support.FindBy; 7 | import org.openqa.selenium.support.How; 8 | import org.openqa.selenium.support.PageFactory; 9 | import org.openqa.selenium.support.ui.ExpectedConditions; 10 | import org.selenium.pom.base.BasePage; 11 | 12 | public class CartPage extends BasePage { 13 | /* private final By productName = By.cssSelector("td[class='product-name'] a"); 14 | private final By checkoutBtn = By.cssSelector(".checkout-button"); 15 | private final By cartHeading = By.cssSelector(".has-text-align-center");*/ 16 | @FindBy(css = "td[class='product-name'] a") private WebElement productName; 17 | @FindBy(how = How.CSS, using = ".checkout-button") @CacheLookup private WebElement checkoutBtn; 18 | 19 | public CartPage(WebDriver driver) { 20 | super(driver); 21 | PageFactory.initElements(driver, this); 22 | } 23 | 24 | public String getProductName(){ 25 | return wait.until(ExpectedConditions.visibilityOf(productName)).getText(); 26 | } 27 | 28 | public CheckoutPage checkout(){ 29 | wait.until(ExpectedConditions.elementToBeClickable(checkoutBtn)).click(); 30 | return new CheckoutPage(driver); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/pages/CheckoutPage.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.pages; 2 | 3 | import org.openqa.selenium.*; 4 | import org.openqa.selenium.support.ui.ExpectedConditions; 5 | import org.selenium.pom.base.BasePage; 6 | import org.selenium.pom.objects.BillingAddress; 7 | import org.selenium.pom.objects.User; 8 | 9 | public class CheckoutPage extends BasePage { 10 | private final By firstnameFld = By.id("billing_first_name"); 11 | private final By lastNameFld = By.id("billing_last_name"); 12 | private final By addressLineOneFld = By.id("billing_address_1"); 13 | private final By billingCityFld = By.id("billing_city"); 14 | private final By billingPostCodeFld = By.id("billing_postcode"); 15 | private final By billingEmailFld = By.id("billing_email"); 16 | private final By placeOrderBtn = By.id("place_order"); 17 | private final By successNotice = By.cssSelector(".woocommerce-notice"); 18 | 19 | private final By clickHereToLoginLink = By.className("showlogin"); 20 | private final By usernameFld = By.id("username"); 21 | private final By passwordFld = By.id("password"); 22 | private final By loginBtn = By.name("login"); 23 | private final By overlay = By.cssSelector(".blockUI.blockOverlay"); 24 | 25 | private final By countryDropDown = By.id("billing_country"); 26 | private final By stateDropDown = By.id("billing_state"); 27 | 28 | private final By alternateCountryDropDown = By.id("select2-billing_country-container"); 29 | private final By alternateStateDropDown = By.id("select2-billing_state-container"); 30 | 31 | private final By directBankTransferRadioBtn = By.id("payment_method_bacs"); 32 | 33 | private final By productName = By.cssSelector("td[class='product-name']"); 34 | 35 | public CheckoutPage(WebDriver driver) { 36 | super(driver); 37 | } 38 | 39 | public CheckoutPage load(){ 40 | load("/checkout/"); 41 | return this; 42 | } 43 | 44 | public CheckoutPage enterFirstName(String firstName){ 45 | WebElement e = wait.until(ExpectedConditions.visibilityOfElementLocated(firstnameFld)); 46 | e.clear(); 47 | e.sendKeys(firstName); 48 | return this; 49 | } 50 | 51 | public CheckoutPage enterLastName(String lastName){ 52 | WebElement e = wait.until(ExpectedConditions.visibilityOfElementLocated(lastNameFld)); 53 | e.clear(); 54 | e.sendKeys(lastName); 55 | return this; 56 | } 57 | 58 | public CheckoutPage selectCountry(String countryName) { 59 | /* Select select = new Select(driver.findElement(countryDropDown)); 60 | select.selectByVisibleText(countryName);*/ 61 | wait.until(ExpectedConditions.elementToBeClickable(alternateCountryDropDown)).click(); 62 | WebElement e = wait.until(ExpectedConditions.elementToBeClickable( 63 | By.xpath("//li[text()='" + countryName + "']"))); 64 | ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", e); 65 | e.click(); 66 | return this; 67 | } 68 | 69 | public CheckoutPage enterAddressLineOne(String addressLineOne){ 70 | WebElement e = wait.until(ExpectedConditions.visibilityOfElementLocated(addressLineOneFld)); 71 | e.clear(); 72 | e.sendKeys(addressLineOne); 73 | return this; 74 | } 75 | 76 | public CheckoutPage enterCity(String city){ 77 | WebElement e = wait.until(ExpectedConditions.visibilityOfElementLocated(billingCityFld)); 78 | e.clear(); 79 | e.sendKeys(city); 80 | return this; 81 | } 82 | 83 | public CheckoutPage selectState(String stateName){ 84 | /* Select select = new Select(driver.findElement(stateDropDown)); 85 | select.selectByVisibleText(stateName);*/ 86 | wait.until(ExpectedConditions.elementToBeClickable(alternateStateDropDown)).click(); 87 | WebElement e = wait.until(ExpectedConditions.elementToBeClickable( 88 | By.xpath("//li[text()='" + stateName + "']"))); 89 | ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", e); 90 | e.click(); 91 | return this; 92 | } 93 | 94 | public CheckoutPage enterPostCode(String postCode){ 95 | WebElement e = wait.until(ExpectedConditions.visibilityOfElementLocated(billingPostCodeFld)); 96 | e.clear(); 97 | e.sendKeys(postCode); 98 | return this; 99 | } 100 | 101 | public CheckoutPage enterEmail(String email){ 102 | WebElement e = wait.until(ExpectedConditions.visibilityOfElementLocated(billingEmailFld)); 103 | e.clear(); 104 | e.sendKeys(email); 105 | return this; 106 | } 107 | 108 | public CheckoutPage setBillingAddress(BillingAddress billingAddress) throws InterruptedException { 109 | return enterFirstName(billingAddress.getFirstName()). 110 | enterLastName(billingAddress.getLastName()). 111 | selectCountry(billingAddress.getCountry()). 112 | enterAddressLineOne(billingAddress.getAddressLineOne()). 113 | enterCity(billingAddress.getCity()). 114 | selectState(billingAddress.getState()). 115 | enterPostCode(billingAddress.getPostalCode()). 116 | enterEmail(billingAddress.getEmail()); 117 | } 118 | 119 | public CheckoutPage placeOrder(){ 120 | waitForOverlaysToDisappear(overlay); 121 | driver.findElement(placeOrderBtn).click(); 122 | return this; 123 | } 124 | 125 | public String getNotice(){ 126 | return wait.until(ExpectedConditions.visibilityOfElementLocated(successNotice)).getText(); 127 | } 128 | 129 | public CheckoutPage clickHereToLoginLink(){ 130 | wait.until(ExpectedConditions.elementToBeClickable(clickHereToLoginLink)).click(); 131 | return this; 132 | } 133 | 134 | public CheckoutPage enterUserName(String username){ 135 | wait.until(ExpectedConditions.visibilityOfElementLocated(usernameFld)).sendKeys(username); 136 | return this; 137 | } 138 | 139 | public CheckoutPage enterPassword(String password){ 140 | wait.until(ExpectedConditions.visibilityOfElementLocated(passwordFld)).sendKeys(password); 141 | return this; 142 | } 143 | 144 | public CheckoutPage clickLoginBtn(){ 145 | wait.until(ExpectedConditions.elementToBeClickable(loginBtn)).click(); 146 | return this; 147 | } 148 | 149 | private CheckoutPage waitForLoginBtnToDisappear(){ 150 | wait.until(ExpectedConditions.invisibilityOfElementLocated(loginBtn)); 151 | return this; 152 | } 153 | 154 | public CheckoutPage login(User user){ 155 | return enterUserName(user.getUsername()). 156 | enterPassword(user.getPassword()). 157 | clickLoginBtn().waitForLoginBtnToDisappear(); 158 | } 159 | 160 | public CheckoutPage selectDirectBankTransfer(){ 161 | WebElement e = wait.until(ExpectedConditions.elementToBeClickable(directBankTransferRadioBtn)); 162 | if(!e.isSelected()){ 163 | e.click(); 164 | } 165 | return this; 166 | } 167 | 168 | public String getProductName() throws Exception { 169 | int i = 5; 170 | while(i > 0){ 171 | try { 172 | return wait.until(ExpectedConditions.visibilityOfElementLocated(productName)).getText(); 173 | }catch (StaleElementReferenceException e){ 174 | System.out.println("NOT FOUND. TRYING AGAIN" + e); 175 | } 176 | Thread.sleep(5000); 177 | i--; 178 | } 179 | throw new Exception("Element not found"); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/pages/HomePage.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.pages; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.selenium.pom.base.BasePage; 5 | import org.selenium.pom.pages.components.MyHeader; 6 | import org.selenium.pom.pages.components.ProductThumbnail; 7 | 8 | public class HomePage extends BasePage { 9 | public MyHeader getMyHeader() { 10 | return myHeader; 11 | } 12 | 13 | public ProductThumbnail getProductThumbnail() { 14 | return productThumbnail; 15 | } 16 | 17 | private MyHeader myHeader; 18 | private ProductThumbnail productThumbnail; 19 | 20 | public HomePage(WebDriver driver) { 21 | super(driver); 22 | myHeader = new MyHeader(driver); 23 | productThumbnail = new ProductThumbnail(driver); 24 | } 25 | 26 | public HomePage load(){ 27 | load("/"); 28 | return this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/pages/StorePage.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.pages; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.support.ui.ExpectedConditions; 6 | import org.selenium.pom.base.BasePage; 7 | import org.selenium.pom.pages.components.ProductThumbnail; 8 | 9 | public class StorePage extends BasePage { 10 | private final By searchFld = By.id("woocommerce-product-search-field-0"); 11 | private final By searchBtn = By.cssSelector("button[value='Search']"); 12 | private final By title = By.cssSelector(".woocommerce-products-header__title.page-title"); 13 | 14 | public ProductThumbnail getProductThumbnail() { 15 | return productThumbnail; 16 | } 17 | 18 | private ProductThumbnail productThumbnail; 19 | 20 | public StorePage(WebDriver driver) { 21 | super(driver); 22 | productThumbnail = new ProductThumbnail(driver); 23 | } 24 | 25 | private StorePage enterTextInSearchFld(String txt){ 26 | wait.until(ExpectedConditions.visibilityOfElementLocated(searchFld)).sendKeys(txt); 27 | return this; 28 | } 29 | 30 | public StorePage load(){ 31 | load("/store"); 32 | return this; 33 | } 34 | 35 | public StorePage search(String txt){ 36 | enterTextInSearchFld(txt).clickSearchBtn(); 37 | return this; 38 | } 39 | 40 | private StorePage clickSearchBtn(){ 41 | wait.until(ExpectedConditions.elementToBeClickable(searchBtn)).click(); 42 | return this; 43 | } 44 | 45 | public String getTitle(){ 46 | return wait.until(ExpectedConditions.visibilityOfElementLocated(title)).getText(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/pages/components/MyHeader.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.pages.components; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.support.ui.ExpectedConditions; 6 | import org.selenium.pom.base.BasePage; 7 | import org.selenium.pom.pages.StorePage; 8 | 9 | public class MyHeader extends BasePage { 10 | private final By storeMenuLink = By.cssSelector("#menu-item-1227 > a"); 11 | 12 | public MyHeader(WebDriver driver) { 13 | super(driver); 14 | } 15 | 16 | public StorePage navigateToStoreUsingMenu(){ 17 | wait.until(ExpectedConditions.elementToBeClickable(storeMenuLink)).click(); 18 | return new StorePage(driver); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/pages/components/ProductThumbnail.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.pages.components; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.support.ui.ExpectedConditions; 6 | import org.selenium.pom.base.BasePage; 7 | import org.selenium.pom.pages.CartPage; 8 | 9 | public class ProductThumbnail extends BasePage { 10 | private final By viewCartLink = By.cssSelector("a[title='View cart']"); 11 | 12 | public ProductThumbnail(WebDriver driver) { 13 | super(driver); 14 | } 15 | 16 | private By getAddToCartBtnElement(String productName){ 17 | return By.cssSelector("a[aria-label='Add “" + productName + "” to your cart']"); 18 | } 19 | 20 | public ProductThumbnail clickAddToCartBtn(String productName){ 21 | By addToCartBtn = getAddToCartBtnElement(productName); 22 | wait.until(ExpectedConditions.elementToBeClickable(addToCartBtn)).click(); 23 | return this; 24 | } 25 | 26 | public CartPage clickViewCart(){ 27 | wait.until(ExpectedConditions.elementToBeClickable(viewCartLink)).click(); 28 | return new CartPage(driver); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/tests/AddToCartTest.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.tests; 2 | 3 | import org.selenium.pom.base.BaseTest; 4 | import org.selenium.pom.dataproviders.MyDataProvider; 5 | import org.selenium.pom.objects.Product; 6 | import org.selenium.pom.pages.CartPage; 7 | import org.selenium.pom.pages.HomePage; 8 | import org.selenium.pom.pages.StorePage; 9 | import org.testng.Assert; 10 | import org.testng.annotations.Test; 11 | 12 | import java.io.IOException; 13 | 14 | public class AddToCartTest extends BaseTest { 15 | 16 | @Test 17 | public void addToCartFromStorePage() throws IOException { 18 | Product product = new Product(1215); 19 | CartPage cartPage = new StorePage(getDriver()).load(). 20 | getProductThumbnail().clickAddToCartBtn(product.getName()). 21 | clickViewCart(); 22 | Assert.assertEquals(cartPage.getProductName(), product.getName()); 23 | } 24 | 25 | @Test(dataProvider = "getFeaturedProducts", dataProviderClass = MyDataProvider.class) 26 | public void addToCartFeaturedProducts(Product product){ 27 | CartPage cartPage = new HomePage(getDriver()).load(). 28 | getProductThumbnail(). 29 | clickAddToCartBtn(product.getName()). 30 | clickViewCart(); 31 | Assert.assertEquals(cartPage.getProductName(), product.getName()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/tests/CheckoutTest.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.tests; 2 | 3 | import org.selenium.pom.api.actions.CartApi; 4 | import org.selenium.pom.api.actions.SignUpApi; 5 | import org.selenium.pom.base.BaseTest; 6 | import org.selenium.pom.objects.BillingAddress; 7 | import org.selenium.pom.objects.Product; 8 | import org.selenium.pom.objects.User; 9 | import org.selenium.pom.pages.CheckoutPage; 10 | import org.selenium.pom.utils.FakerUtils; 11 | import org.selenium.pom.utils.JacksonUtils; 12 | import org.testng.Assert; 13 | import org.testng.annotations.Test; 14 | 15 | import java.io.IOException; 16 | 17 | public class CheckoutTest extends BaseTest { 18 | 19 | @Test 20 | public void GuestCheckoutUsingDirectBankTransfer() throws IOException, InterruptedException { 21 | BillingAddress billingAddress = JacksonUtils.deserializeJson("myBillingAddress.json", BillingAddress.class); 22 | CheckoutPage checkoutPage = new CheckoutPage(getDriver()).load(); 23 | 24 | CartApi cartApi = new CartApi(); 25 | cartApi.addToCart(1215, 1); 26 | injectCookiesToBrowser(cartApi.getCookies()); 27 | 28 | checkoutPage.load(). 29 | setBillingAddress(billingAddress). 30 | selectDirectBankTransfer(). 31 | placeOrder(); 32 | Assert.assertEquals(checkoutPage.getNotice(), "Thank you. Your order has been received."); 33 | } 34 | 35 | @Test 36 | public void LoginAndCheckoutUsingDirectBankTransfer() throws IOException, InterruptedException { 37 | BillingAddress billingAddress = JacksonUtils.deserializeJson("myBillingAddress.json", BillingAddress.class); 38 | String username = "demouser" + new FakerUtils().generateRandomNumber(); 39 | User user = new User(). 40 | setUsername(username). 41 | setPassword("demopwd"). 42 | setEmail(username + "@askomdch.com"); 43 | 44 | SignUpApi signUpApi = new SignUpApi(); 45 | signUpApi.register(user); 46 | CartApi cartApi = new CartApi(signUpApi.getCookies()); 47 | Product product = new Product(1215); 48 | cartApi.addToCart(product.getId(), 1); 49 | 50 | CheckoutPage checkoutPage = new CheckoutPage(getDriver()).load(); 51 | injectCookiesToBrowser(signUpApi.getCookies()); 52 | checkoutPage.load(); 53 | checkoutPage.setBillingAddress(billingAddress). 54 | selectDirectBankTransfer(). 55 | placeOrder(); 56 | Assert.assertEquals(checkoutPage.getNotice(), "Thank you. Your order has been received."); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/tests/LoginTest.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.tests; 2 | 3 | import org.selenium.pom.api.actions.CartApi; 4 | import org.selenium.pom.api.actions.SignUpApi; 5 | import org.selenium.pom.base.BaseTest; 6 | import org.selenium.pom.objects.Product; 7 | import org.selenium.pom.objects.User; 8 | import org.selenium.pom.pages.CheckoutPage; 9 | import org.selenium.pom.utils.FakerUtils; 10 | import org.testng.Assert; 11 | import org.testng.annotations.Test; 12 | 13 | public class LoginTest extends BaseTest { 14 | 15 | @Test 16 | public void loginDuringCheckout() throws Exception { 17 | String username = "demouser" + new FakerUtils().generateRandomNumber(); 18 | User user = new User(). 19 | setUsername(username). 20 | setPassword("demopwd"). 21 | setEmail(username + "@askomdch.com"); 22 | 23 | SignUpApi signUpApi = new SignUpApi(); 24 | signUpApi.register(user); 25 | CartApi cartApi = new CartApi(); 26 | Product product = new Product(1215); 27 | cartApi.addToCart(product.getId(), 1); 28 | 29 | CheckoutPage checkoutPage = new CheckoutPage(getDriver()).load(); 30 | injectCookiesToBrowser(cartApi.getCookies()); 31 | checkoutPage.load(); 32 | checkoutPage. 33 | clickHereToLoginLink(). 34 | login(user); 35 | Assert.assertTrue(checkoutPage.getProductName().contains(product.getName())); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/tests/MyFirstTestCase.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.tests; 2 | 3 | import org.selenium.pom.base.BaseTest; 4 | import org.selenium.pom.objects.BillingAddress; 5 | import org.selenium.pom.objects.Product; 6 | import org.selenium.pom.objects.User; 7 | import org.selenium.pom.pages.CartPage; 8 | import org.selenium.pom.pages.CheckoutPage; 9 | import org.selenium.pom.pages.HomePage; 10 | import org.selenium.pom.pages.StorePage; 11 | import org.selenium.pom.utils.ConfigLoader; 12 | import org.selenium.pom.utils.JacksonUtils; 13 | import org.testng.Assert; 14 | 15 | import java.io.IOException; 16 | 17 | public class MyFirstTestCase extends BaseTest { 18 | 19 | // @Test 20 | public void guestCheckoutUsingDirectBankTransfer() throws IOException, InterruptedException { 21 | String searchFor = "Blue"; 22 | BillingAddress billingAddress = JacksonUtils.deserializeJson("myBillingAddress.json", BillingAddress.class); 23 | Product product = new Product(1215); 24 | 25 | StorePage storePage = new HomePage(getDriver()). 26 | load(). 27 | getMyHeader().navigateToStoreUsingMenu() 28 | .search(searchFor); 29 | Assert.assertEquals(storePage.getTitle(), "Search results: “" + searchFor + "”"); 30 | 31 | storePage.getProductThumbnail().clickAddToCartBtn(product.getName()); 32 | CartPage cartPage = storePage.getProductThumbnail().clickViewCart(); 33 | Assert.assertEquals(cartPage.getProductName(), product.getName()); 34 | 35 | CheckoutPage checkoutPage = cartPage. 36 | checkout(). 37 | setBillingAddress(billingAddress). 38 | selectDirectBankTransfer(). 39 | placeOrder(); 40 | Assert.assertEquals(checkoutPage.getNotice(), "Thank you. Your order has been received."); 41 | } 42 | 43 | // @Test 44 | public void loginAndCheckoutUsingDirectBankTransfer() throws IOException, InterruptedException { 45 | String searchFor = "Blue"; 46 | BillingAddress billingAddress = JacksonUtils.deserializeJson("myBillingAddress.json", BillingAddress.class); 47 | Product product = new Product(1215); 48 | User user = new User(ConfigLoader.getInstance().getUsername(), 49 | ConfigLoader.getInstance().getPassword()); 50 | 51 | StorePage storePage = new HomePage(getDriver()). 52 | load().getMyHeader(). 53 | navigateToStoreUsingMenu(). 54 | search(searchFor); 55 | Assert.assertEquals(storePage.getTitle(), "Search results: “" + searchFor + "”"); 56 | 57 | storePage.getProductThumbnail().clickAddToCartBtn(product.getName()); 58 | CartPage cartPage = storePage.getProductThumbnail().clickViewCart(); 59 | Assert.assertEquals(cartPage.getProductName(), product.getName()); 60 | 61 | CheckoutPage checkoutPage = cartPage.checkout(); 62 | checkoutPage.clickHereToLoginLink(); 63 | 64 | checkoutPage. 65 | login(user). 66 | setBillingAddress(billingAddress). 67 | selectDirectBankTransfer(). 68 | placeOrder(); 69 | Assert.assertEquals(checkoutPage.getNotice(), "Thank you. Your order has been received."); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/tests/NavigationTest.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.tests; 2 | 3 | import org.selenium.pom.base.BaseTest; 4 | import org.selenium.pom.pages.HomePage; 5 | import org.selenium.pom.pages.StorePage; 6 | import org.testng.Assert; 7 | import org.testng.annotations.Test; 8 | 9 | public class NavigationTest extends BaseTest { 10 | 11 | @Test 12 | public void NavigateFromHomeToStoreUsingMainMenu(){ 13 | StorePage storePage = new HomePage(getDriver()). 14 | load().getMyHeader(). 15 | navigateToStoreUsingMenu(); 16 | Assert.assertEquals(storePage.getTitle(), "Store"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/tests/SearchTest.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.tests; 2 | 3 | import org.selenium.pom.base.BaseTest; 4 | import org.selenium.pom.pages.StorePage; 5 | import org.testng.Assert; 6 | import org.testng.annotations.Test; 7 | 8 | public class SearchTest extends BaseTest { 9 | 10 | @Test 11 | public void searchWithPartialMatch(){ 12 | String searchFor = "Blue"; 13 | StorePage storePage = new StorePage(getDriver()). 14 | load(). 15 | search(searchFor); 16 | Assert.assertEquals(storePage.getTitle(), "Search results: “" + searchFor + "”"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/utils/ConfigLoader.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.utils; 2 | 3 | import org.selenium.pom.constants.EnvType; 4 | 5 | import java.util.Properties; 6 | 7 | public class ConfigLoader { 8 | private final Properties properties; 9 | private static ConfigLoader configLoader; 10 | 11 | private ConfigLoader(){ 12 | String env = System.getProperty("env", String.valueOf(EnvType.STAGE)); 13 | switch (EnvType.valueOf(env)) { 14 | case STAGE -> properties = PropertyUtils.propertyLoader("src/test/resources/stg_config.properties"); 15 | case PRODUCTION -> properties = PropertyUtils.propertyLoader("src/test/resources/prod_config.properties"); 16 | default -> throw new IllegalStateException("Invalid env type: " + env); 17 | } 18 | } 19 | 20 | public static ConfigLoader getInstance(){ 21 | if(configLoader == null){ 22 | configLoader = new ConfigLoader(); 23 | } 24 | return configLoader; 25 | } 26 | 27 | public String getBaseUrl(){ 28 | String prop = properties.getProperty("baseUrl"); 29 | if(prop != null) return prop; 30 | else throw new RuntimeException("property baseUrl is not specified in the stg_config.properties file"); 31 | } 32 | 33 | public String getUsername(){ 34 | String prop = properties.getProperty("username"); 35 | if(prop != null) return prop; 36 | else throw new RuntimeException("property username is not specified in the stg_config.properties file"); 37 | } 38 | 39 | public String getPassword(){ 40 | String prop = properties.getProperty("password"); 41 | if(prop != null) return prop; 42 | else throw new RuntimeException("property password is not specified in the stg_config.properties file"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/utils/CookieUtils.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.utils; 2 | 3 | import io.restassured.http.Cookies; 4 | import org.openqa.selenium.Cookie; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class CookieUtils { 10 | 11 | public List convertRestAssuredCookiesToSeleniumCookies(Cookies cookies){ 12 | List restAssuredCookies = new ArrayList<>(); 13 | restAssuredCookies = cookies.asList(); 14 | List seleniumCookies = new ArrayList<>(); 15 | for(io.restassured.http.Cookie cookie: restAssuredCookies){ 16 | seleniumCookies.add(new Cookie(cookie.getName(), cookie.getValue(), cookie.getDomain(), 17 | cookie.getPath(), cookie.getExpiryDate(), cookie.isSecured(), cookie.isHttpOnly(), 18 | cookie.getSameSite())); 19 | } 20 | return seleniumCookies; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/utils/FakerUtils.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.utils; 2 | 3 | import com.github.javafaker.Faker; 4 | 5 | public class FakerUtils { 6 | 7 | public Long generateRandomNumber(){ 8 | Faker faker = new Faker(); 9 | return faker.number().randomNumber(10, true); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/utils/JacksonUtils.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.utils; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | 8 | public class JacksonUtils { 9 | 10 | public static T deserializeJson(String fileName, Class T) throws IOException { 11 | InputStream is = JacksonUtils.class.getClassLoader().getResourceAsStream(fileName); 12 | ObjectMapper objectMapper = new ObjectMapper(); 13 | return objectMapper.readValue(is, T); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/org/selenium/pom/utils/PropertyUtils.java: -------------------------------------------------------------------------------- 1 | package org.selenium.pom.utils; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileReader; 6 | import java.io.IOException; 7 | import java.util.Properties; 8 | 9 | public class PropertyUtils { 10 | 11 | public static Properties propertyLoader(String filePath) { 12 | Properties properties = new Properties(); 13 | BufferedReader reader; 14 | try { 15 | reader = new BufferedReader(new FileReader(filePath)); 16 | try { 17 | properties.load(reader); 18 | reader.close(); 19 | } catch (IOException e) { 20 | e.printStackTrace(); 21 | throw new RuntimeException("failed to load properties file "+ filePath); 22 | } 23 | } catch (FileNotFoundException e) { 24 | e.printStackTrace(); 25 | throw new RuntimeException("properties file not found at " + filePath); 26 | } 27 | return properties; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/resources/myBillingAddress.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstName": "demo", 3 | "lastName": "user", 4 | "country": "India", 5 | "addressLineOne": "Pune", 6 | "city": "Pune", 7 | "state": "Maharashtra", 8 | "postalCode": "411001", 9 | "email": "askomdch@gmail.com" 10 | } -------------------------------------------------------------------------------- /src/test/resources/prod_config.properties: -------------------------------------------------------------------------------- 1 | baseUrl=https://prod.askomdch.com 2 | username= 3 | password= -------------------------------------------------------------------------------- /src/test/resources/products.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1215, 4 | "name": "Blue Shoes" 5 | }, 6 | { 7 | "id": 1209, 8 | "name": "Denim Blue Jeans" 9 | }, 10 | { 11 | "id": 1205, 12 | "name": "Basic Blue Jeans" 13 | }, 14 | { 15 | "id": 1198, 16 | "name": "Anchor Bracelet" 17 | }, 18 | { 19 | "id": 1196, 20 | "name": "Blue Tshirt" 21 | } 22 | ] -------------------------------------------------------------------------------- /src/test/resources/stg_config.properties: -------------------------------------------------------------------------------- 1 | baseUrl=https://askomdch.com 2 | username=demouser2 3 | password=demopwd -------------------------------------------------------------------------------- /testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 20 | 21 | --------------------------------------------------------------------------------