├── .gitignore
├── .idea
├── .gitignore
├── aws.xml
├── encodings.xml
├── misc.xml
└── vcs.xml
├── README.md
├── pom.xml
├── src
├── main
│ ├── java
│ │ └── com
│ │ │ └── framework
│ │ │ ├── base
│ │ │ ├── BasePage.java
│ │ │ ├── CommonMethods.java
│ │ │ └── Product.java
│ │ │ ├── exceptions
│ │ │ └── PageLoadException.java
│ │ │ ├── factory
│ │ │ ├── Constant.java
│ │ │ ├── DBFactory.java
│ │ │ └── DriverFactory.java
│ │ │ ├── listener
│ │ │ ├── CustomListener.java
│ │ │ └── RetryAnalyzer.java
│ │ │ ├── pages
│ │ │ ├── Account.java
│ │ │ ├── HomePage.java
│ │ │ ├── Login.java
│ │ │ ├── Register.java
│ │ │ ├── Search.java
│ │ │ └── ShoppingCart.java
│ │ │ ├── reporting
│ │ │ └── TestLog.java
│ │ │ └── utils
│ │ │ ├── ScreenshotUtil.java
│ │ │ └── WaitUtils.java
│ └── resources
│ │ └── log4j.properties
└── test
│ ├── java
│ └── com
│ │ ├── base
│ │ └── BaseTest.java
│ │ └── tests
│ │ ├── account
│ │ └── RegistrationFlowTest.java
│ │ ├── cart
│ │ ├── AddToCartTest.java
│ │ ├── ModifyCartTest.java
│ │ └── RemoveFromCartTest.java
│ │ ├── login
│ │ ├── LoginTest.java
│ │ └── LogoutTest.java
│ │ ├── search
│ │ ├── AddToCart.java
│ │ ├── AddToWishListTest.java
│ │ ├── FilterSearchTest.java
│ │ └── SearchTest.java
│ │ └── wishlist
│ │ ├── AddToWishListTest.java
│ │ ├── ModifyWishListTest.java
│ │ └── RemoveFromWishListTest.java
│ └── resources
│ └── screenshots
│ ├── addProductToWishListByIndex_1746775387469.png
│ ├── registerUser_1747220308640.png
│ └── registerUser_1747220404214.png
├── testng-regression.xml
├── testng-smoke.xml
└── testng.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 | ### IntelliJ IDEA ###
7 | .idea/modules.xml
8 | .idea/jarRepositories.xml
9 | .idea/compiler.xml
10 | .idea/libraries/
11 | *.iws
12 | *.iml
13 | *.ipr
14 |
15 | ### Eclipse ###
16 | .apt_generated
17 | .classpath
18 | .factorypath
19 | .project
20 | .settings
21 | .springBeans
22 | .sts4-cache
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 | !**/src/main/**/build/
32 | !**/src/test/**/build/
33 |
34 | ### VS Code ###
35 | .vscode/
36 |
37 | ### Mac OS ###
38 | .DS_Store
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 | /allure-results
10 | /allure-reports
11 | /logs
12 |
--------------------------------------------------------------------------------
/.idea/aws.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | UIAutomation
2 |
3 | 🔗 Test Website: OpenCart Demo
4 |
5 | 📌 Project Overview This is a Selenium-based UI automation framework built using Java and TestNG, designed for maintainability, scalability, and ease of use. The framework demonstrates modern design principles and automation best practices.
6 |
7 | Language: Java
8 |
9 | Test Framework: TestNG
10 |
11 | Design Patterns:
12 |
13 | ✅ Page Object Model (POM)
14 |
15 | ✅ Factory Pattern (for browser setup)
16 |
17 | ✅ Builder Pattern (for test data or page components)
18 |
19 | OOP Concepts: Abstraction, Encapsulation, Inheritance, Polymorphism
20 |
21 |
22 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.example
8 | UIAutomation
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 17
13 | 17
14 | UTF-8
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | org.apache.maven.plugins
24 | maven-surefire-plugin
25 | 3.0.0
26 |
27 |
28 | testng.xml
29 |
30 |
31 | allure-results
32 |
33 |
34 |
35 |
36 |
37 |
38 | io.qameta.allure
39 | allure-maven
40 | 2.11.2
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | org.seleniumhq.selenium
49 | selenium-java
50 | 4.10.0
51 |
52 |
53 |
54 |
55 | org.testng
56 | testng
57 | 7.9.0
58 | test
59 |
60 |
61 | io.github.bonigarcia
62 | webdrivermanager
63 | 5.7.0
64 |
65 |
66 |
67 |
68 |
69 |
70 | io.qameta.allure
71 | allure-testng
72 | 2.22.1
73 |
74 |
75 |
76 | log4j
77 | log4j
78 | 1.2.17
79 |
80 |
81 |
82 |
83 | com.fasterxml.jackson.core
84 | jackson-databind
85 | 2.15.2
86 |
87 |
88 | org.testng
89 | testng
90 | 7.10.2
91 | compile
92 |
93 |
94 | org.projectlombok
95 | lombok
96 | 1.18.20
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/base/BasePage.java:
--------------------------------------------------------------------------------
1 | package com.framework.base;
2 |
3 | import com.framework.utils.WaitUtils;
4 | import org.openqa.selenium.By;
5 | import org.openqa.selenium.JavascriptExecutor;
6 | import org.openqa.selenium.WebDriver;
7 | import org.openqa.selenium.WebElement;
8 | import org.openqa.selenium.support.ui.Select;
9 |
10 | public class BasePage {
11 |
12 | protected WebDriver driver;
13 | public String product = "2";
14 |
15 | public BasePage(WebDriver driver) {
16 | this.driver = driver;
17 | }
18 |
19 | public void click(WebElement element) {
20 |
21 | ((JavascriptExecutor) driver).executeScript("arguments[0].style.display='block';", element);
22 | WaitUtils.waitForClickable(driver, element).click();
23 |
24 | }
25 |
26 | public void click(By locator, int timeout, int polling) {
27 | WaitUtils.fluentWait(driver, locator, 10, 1).click();
28 | }
29 |
30 | public void clear(WebElement element) {
31 | WaitUtils.waitForClickable(driver, element).clear();
32 | }
33 |
34 |
35 | public void enterText(WebElement element, String text) {
36 | clear(element);
37 | element.sendKeys(text);
38 |
39 | }
40 |
41 | public String getTitle(WebDriver driver) {
42 | return driver.getTitle();
43 | }
44 |
45 | public void searchFromDropdownByText(WebElement element,String text){
46 |
47 | Select dropDown= new Select(element);
48 | dropDown. selectByVisibleText(text);
49 |
50 |
51 | }
52 |
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/base/CommonMethods.java:
--------------------------------------------------------------------------------
1 | package com.framework.base;
2 |
3 | import com.framework.factory.Constant;
4 | import com.framework.utils.WaitUtils;
5 | import org.openqa.selenium.WebDriver;
6 | import org.openqa.selenium.WebElement;
7 | import org.openqa.selenium.support.ui.ExpectedCondition;
8 | import org.openqa.selenium.support.ui.WebDriverWait;
9 |
10 | import java.time.Duration;
11 | import java.util.Currency;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | public class CommonMethods {
16 |
17 | public int returnProductIndex(String productName) {
18 |
19 | Map map = Map.ofEntries(
20 | Map.entry("MacBook", 1),
21 | Map.entry("iPhone", 2),
22 | Map.entry("Apple Cinema 30", 3),
23 | Map.entry("Canon EOS 5D", 4)
24 | );
25 |
26 | return map.get(productName);
27 | }
28 |
29 | public static String removeCurrencySymbols(String input) {
30 | if (input.contains(Constant.CURRENCY_DOLLAR))
31 | return input.replaceAll("[$,]", "");
32 | else if (input.contains(Constant.CURRENCY_EURO))
33 | return input.replaceAll("[€,]", "");
34 | else if (input.contains(Constant.CURRENCY_POUND)) {
35 | return input.replaceAll("[£,]", "");
36 |
37 | }
38 | return "";
39 |
40 | }
41 |
42 | //return sorted ascending or descending list
43 | public static > boolean isSorted(List list, boolean ascending) {
44 | for (int i = 0; i < list.size() - 1; i++) {
45 | int cmp = list.get(i).compareTo(list.get(i + 1));
46 | if ((ascending && cmp > 0) || (!ascending && cmp < 0)) {
47 | return false;
48 | }
49 | }
50 | return true;
51 | }
52 |
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/base/Product.java:
--------------------------------------------------------------------------------
1 | package com.framework.base;
2 | import lombok.*;
3 |
4 | @Getter
5 | @Setter
6 | @Builder
7 | @AllArgsConstructor
8 | @NoArgsConstructor
9 | public class Product {
10 |
11 | String addToCartXpath;
12 | String addToWishlistXpath;
13 | String productName;
14 | String productId;
15 | Double productPrice;
16 |
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/exceptions/PageLoadException.java:
--------------------------------------------------------------------------------
1 | package com.framework.exceptions;
2 |
3 |
4 | public class PageLoadException extends Exception {
5 |
6 |
7 | public PageLoadException(String msg) {
8 |
9 | super(msg);
10 |
11 | }
12 |
13 | public PageLoadException(String message, Throwable cause) {
14 | super(message, cause);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/factory/Constant.java:
--------------------------------------------------------------------------------
1 | package com.framework.factory;
2 |
3 | public class Constant {
4 |
5 | public static String BASE_URL="https://naveenautomationlabs.com/opencart/index.php?route=common/home";
6 |
7 | public static String EMAIL_ADDRESS="abhishek007@gmail.com";
8 |
9 | public static String PWD="Patna246" ;
10 |
11 | public static final String HOME_PAGE_TITLE="Your Store";
12 |
13 | public static final String LOGIN_PAGE_TITLE="Account Login";
14 |
15 | public static final String ACCOUNT_PAGE_TITLE="My Account";
16 |
17 | public static final String REGISTER_PAGE_TITLE="Register Account";
18 |
19 | public static final String LOGOUT_PAGE_TITLE="Account Logout";
20 |
21 | public static final String SEARCH_PAGE_TITLE="Search";
22 |
23 | public static final String INVALID_USER_WARNING="Warning: No match for E-Mail Address and/or Password.";
24 |
25 | public static final String ACCOUNT_PAGE_SUCCESS_TITLE="Your Account Has Been Created!";
26 | public static final String SHOPPING_CART_PAGE_TITLE= "Shopping Cart";
27 | public static final String WISHLIST_PAGE_TITLE="My Wish List";
28 |
29 | public static final String CURRENCY_DOLLAR="$";
30 | public static final String CURRENCY_POUND="£";
31 | public static final String CURRENCY_EURO="€";
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/factory/DBFactory.java:
--------------------------------------------------------------------------------
1 | package com.framework.factory;
2 |
3 | import org.slf4j.Logger;
4 | import com.framework.reporting.TestLog;
5 |
6 | import java.sql.*;
7 |
8 | public class DBFactory {
9 |
10 | public static Connection stageConnection, prodConnection, integConnection;
11 | public static Statement stmt = null;
12 | static ResultSet rs = null;
13 | public Connection connection;
14 | Logger log = org.slf4j.LoggerFactory.getLogger("DBFactory");
15 |
16 | public DBFactory(String DB_URL, String DB_User, String DB_Password, String connectionType) {
17 | try {
18 | Class.forName("com.mysql.jdbc.Driver");
19 | if (connectionType.equals("stage"))
20 | stageConnection = DriverManager.getConnection(DB_URL, DB_User, DB_Password);
21 | else if (connectionType.equals("prod"))
22 | prodConnection = DriverManager.getConnection(DB_URL, DB_User, DB_Password);
23 | else if (connectionType.equals("integ"))
24 | integConnection = DriverManager.getConnection(DB_URL, DB_User, DB_Password);
25 | } catch (Exception e) {
26 | e.printStackTrace();
27 | }
28 | }
29 |
30 | public static ResultSet selectQuery(String query, Connection connection) {
31 | try {
32 | stmt = connection.createStatement();
33 | rs = stmt.executeQuery(query);
34 | } catch (SQLException e) {
35 | TestLog.stepInfo("SQL exception occurred while executing the query: " + e.getMessage());
36 | e.printStackTrace();
37 | } catch (Exception e) {
38 | e.printStackTrace();
39 | }
40 |
41 | return rs;
42 | }
43 |
44 | public static ResultSet updateQuery(String query, Connection connection) {
45 | try {
46 | stmt = connection.createStatement();
47 | stmt.executeUpdate(query);
48 |
49 | } catch (Exception e) {
50 | e.printStackTrace();
51 | }
52 | return rs;
53 | }
54 |
55 | public DBFactory(String DB_URL, String DB_User, String DB_Password) {
56 | try {
57 | Class.forName("com.mysql.jdbc.Driver");
58 | connection = DriverManager.getConnection(DB_URL, DB_User, DB_Password);
59 | } catch (ClassNotFoundException | SQLException e) {
60 | e.printStackTrace();
61 | }
62 |
63 | }
64 |
65 | public Connection connectDb(String DB_URL, String DB_User, String DB_Password) {
66 | try {
67 |
68 | Class.forName("com.mysql.jdbc.Driver");
69 | return DriverManager.getConnection(DB_URL, DB_User, DB_Password);
70 |
71 | } catch (ClassNotFoundException | SQLException e) {
72 | e.printStackTrace();
73 | }
74 | return null;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/factory/DriverFactory.java:
--------------------------------------------------------------------------------
1 | package com.framework.factory;
2 |
3 | import org.openqa.selenium.WebDriver;
4 | import org.openqa.selenium.chrome.ChromeDriver;
5 | import org.openqa.selenium.chrome.ChromeDriverService;
6 | import org.openqa.selenium.chrome.ChromeOptions;
7 | import org.openqa.selenium.firefox.FirefoxDriver;
8 | import org.openqa.selenium.safari.SafariDriver;
9 |
10 | import java.time.Duration;
11 |
12 | public class DriverFactory {
13 |
14 |
15 | public static WebDriver getDriver(String driverName) {
16 | WebDriver driver;
17 |
18 | switch (driverName.toLowerCase()) {
19 | case "chrome":
20 | System.setProperty("webdriver.chrome.driver", "/Users/kumar.mangalam/Downloads/chromedriver-mac-x64/chromedriver");
21 | ChromeOptions chromeOptions = new ChromeOptions();
22 | chromeOptions.addArguments("--remote-allow-origins=*");
23 | chromeOptions.addArguments("--no-sandbox");
24 | chromeOptions.addArguments("--disable-gpu");
25 | chromeOptions.addArguments("--disable-blink-features=AutomationControlled");
26 | chromeOptions.addArguments("--disable-extensions"); // Disable extensions
27 | chromeOptions.addArguments("--no-sandbox"); // Bypass OS security model
28 | chromeOptions.addArguments("--disable-dev-shm-usage");
29 | //chromeOptions.addArguments("--headless");
30 |
31 | ChromeDriverService service = new ChromeDriverService.Builder()
32 | .withLogOutput(System.out) // Send logs to console again
33 | .build();
34 | driver = new ChromeDriver(service, chromeOptions);
35 | break;
36 | case "firefox":
37 | driver = new FirefoxDriver();
38 | break;
39 | case "safari":
40 | driver = new SafariDriver();
41 | break;
42 |
43 | default:
44 | throw new RuntimeException("Driver Not Supported " + driverName);
45 |
46 |
47 | }
48 | driver.manage().window().maximize();
49 | driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
50 | return driver;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/listener/CustomListener.java:
--------------------------------------------------------------------------------
1 | package com.framework.listener;
2 |
3 | import org.testng.ITestListener;
4 |
5 | import org.testng.ITestResult;
6 |
7 | public class CustomListener implements ITestListener {
8 |
9 | @Override
10 | public void onTestFailure(ITestResult result) {
11 | System.out.println("Test failed: " + result.getName());
12 |
13 | }
14 |
15 |
16 | @Override
17 | public void onTestSuccess(ITestResult result) {
18 | System.out.println("Test passed: " + result.getName());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/listener/RetryAnalyzer.java:
--------------------------------------------------------------------------------
1 | package com.framework.listener;
2 |
3 | import org.testng.IRetryAnalyzer;
4 | import org.testng.ITestResult;
5 |
6 | public class RetryAnalyzer implements IRetryAnalyzer {
7 |
8 |
9 | private int retryCount = 0;
10 | private static final int maxRetry = 2;
11 |
12 | public boolean retry(ITestResult iTestResult){
13 |
14 | if(retryCount e.isDisplayed() && e.isEnabled()).ifPresentOrElse(
116 | e -> TestLog.stepInfo(elementName + " is visible and enabled."), () ->
117 | {
118 | throw new AssertionError(elementName + " is not visible or enabled.");
119 | }
120 |
121 | );
122 |
123 |
124 | }
125 |
126 |
127 | public static class UpdatePassword extends Account {
128 |
129 | public UpdatePassword(WebDriver driver) {
130 | super(driver);
131 | PageFactory.initElements(driver, this);
132 | }
133 |
134 | @FindBy(id = "input-password")
135 | private WebElement enterPwd;
136 |
137 | @FindBy(id = "input-confirm")
138 | private WebElement cnfirmPwd;
139 |
140 | @FindBy(xpath = "//input[@value='Continue']")
141 | private WebElement continueBtn;
142 |
143 | @FindBy(xpath = "//a[text()='Back']")
144 | private WebElement bckBtn;
145 |
146 | public void updatePwd(String currentPwd, String newPwd) {
147 |
148 | enterText(enterPwd, currentPwd);
149 | enterText(cnfirmPwd, newPwd);
150 | click(continueBtn);
151 |
152 | }
153 |
154 | public Account naviagteToAccountsPage(WebDriver driver) {
155 |
156 | click(continueBtn);
157 | return new Account(driver);
158 |
159 | }
160 |
161 | }
162 |
163 | public static class EditAccountPage extends Account {
164 |
165 | public EditAccountPage(WebDriver driver) {
166 | super(driver);
167 | PageFactory.initElements(driver, this);
168 |
169 | }
170 |
171 | @FindBy(id = "input-firstname")
172 | private WebElement firstName;
173 |
174 | @FindBy(id = "input-lastname")
175 | private WebElement lastName;
176 |
177 | @FindBy(id = "input-email")
178 | private WebElement email;
179 |
180 | @FindBy(id = "input-telephone")
181 | private WebElement telephone;
182 |
183 | @FindBy(xpath = "//a[text()='Back']")
184 | private WebElement backBtn;
185 |
186 | @FindBy(xpath = "//input[@value='Continue']")
187 | private WebElement continueBtn;
188 |
189 | public void updateAccount(String firstNameValue, String lastNameValue, String emailValue, String phoneValue) {
190 |
191 | enterText(firstName, firstNameValue);
192 | enterText(lastName, lastNameValue);
193 | enterText(email, emailValue);
194 | enterText(telephone, phoneValue);
195 | click(continueBtn);
196 | }
197 |
198 |
199 | public Account backToAccountPage() {
200 |
201 | click(backBtn);
202 | return new Account(driver);
203 |
204 | }
205 |
206 |
207 | }
208 |
209 | public static class Logout extends Account {
210 |
211 | public Logout(WebDriver driver) {
212 | super(driver);
213 | PageFactory.initElements(driver, this);
214 | }
215 |
216 | @FindBy(xpath = "//h1[text()='Account Logout']")
217 | private WebElement accountLogout;
218 |
219 | @FindBy(xpath = "//p[text()='You have been logged off your account. It is now safe to leave the computer.']")
220 | private WebElement loggOffMsg;
221 |
222 | @FindBy(xpath = "//p[text()='Your shopping cart has been saved, the items inside it will be restored whenever you log back into your account.']")
223 | private WebElement logoutMsg;
224 |
225 | @FindBy(xpath = "//a[text()='Continue']")
226 | private WebElement continueBtn;
227 |
228 | public HomePage navigateToHomePage() {
229 | click(continueBtn);
230 | return new HomePage(driver);
231 | }
232 |
233 | public boolean isLogOffMsgDisplayed() {
234 | return WaitUtils.waitFor(ExpectedConditions.visibilityOf(loggOffMsg),driver,5).isDisplayed();
235 | }
236 |
237 | public boolean isLogOutMsgDisplayed() {
238 | return WaitUtils.waitFor(ExpectedConditions.visibilityOf(logoutMsg),driver,5).isDisplayed();
239 | }
240 |
241 | public boolean isAccountLogoutDisplayed() {
242 | return WaitUtils.waitFor(ExpectedConditions.visibilityOf(accountLogout),driver,5).isDisplayed();
243 | }
244 |
245 | public boolean isContinueBtnEnabled() {
246 | return WaitUtils.waitFor(ExpectedConditions.elementToBeClickable(continueBtn),driver,5).isEnabled();
247 | }
248 |
249 |
250 | }
251 |
252 | public static class Success extends Account {
253 |
254 | public Success(WebDriver driver) {
255 | super(driver);
256 | PageFactory.initElements(driver, this);
257 |
258 | }
259 |
260 | @FindBy(xpath = "//h1[contains(text(), 'Your Account Has Been Created!')]")
261 | WebElement accountCreation;
262 |
263 | @FindBy(xpath = "//p[contains(text(), 'Congratulations! Your new account has been successfully created!')]")
264 | WebElement congratulationMsg;
265 |
266 | @FindBy(xpath = "//p[contains(text(), 'If you have ANY questions about the operation of this online shop, please e-mail the store owner.')]")
267 | WebElement queryMsg;
268 |
269 | @FindBy(xpath = "//a[contains(@href, 'account/account') and contains(text(), 'Continue')]")
270 | WebElement continueBtn;
271 |
272 | public Account navigateToAccountPage() {
273 |
274 | WaitUtils.waitForClickable(driver, continueBtn).click();
275 | return new Account(driver);
276 | }
277 |
278 | public void verifyAccountSuccessPageElements() {
279 | verifyElementVisibleAndEnabled(accountCreation, "Account Creation Heading");
280 | verifyElementVisibleAndEnabled(congratulationMsg, "Congratulations Message");
281 | verifyElementVisibleAndEnabled(queryMsg, "Query Message");
282 | verifyElementVisibleAndEnabled(continueBtn, "Continue Button");
283 | }
284 |
285 | private void verifyElementVisibleAndEnabled(WebElement element, String elementName) {
286 | if (element.isDisplayed() || element.isEnabled()) {
287 | TestLog.stepInfo(elementName + " is visible or enabled.");
288 | } else {
289 | throw new AssertionError(elementName + " is NOT visible or enabled.");
290 | }
291 | }
292 |
293 |
294 | }
295 |
296 | public static class WishList extends Account {
297 |
298 | public WishList(WebDriver driver) {
299 | super(driver);
300 | PageFactory.initElements(driver, this);
301 |
302 | }
303 |
304 | @FindBy(xpath = "//p[contains(text(), 'Your wish list is empty.')]")
305 | WebElement emptyWishList;
306 |
307 | @FindBy(xpath = "//a[contains(@href, 'account/account') and contains(text(), 'Continue')]")
308 | WebElement continueBtn;
309 |
310 | @Getter
311 | @FindBy(xpath = "//table[contains(@class,'table table-bordered table-hover')]/tbody/tr")
312 | List wishList;
313 |
314 | @FindBy(xpath = "//div[contains(@class,'alert alert-success alert-dismissible')and contains(text(),' Success: You have modified your wish list!')]")
315 | WebElement wishListModification;
316 |
317 | @FindBy(xpath = "//a[@title='Shopping Cart']")
318 | WebElement shoppingCartBtn;
319 |
320 | public boolean verifyEmptyWishList() {
321 |
322 | return WaitUtils.waitForVisibility(this.driver, emptyWishList).isDisplayed();
323 | }
324 |
325 | public String getProductName(int productIndex) {
326 |
327 | String xpath = "//table[contains(@class,'table table-bordered table-hover')]/tbody/tr[" + productIndex + "]//td[2]/a";
328 | return WaitUtils.waitForVisibility(this.driver, driver.findElement(By.xpath(xpath))).getText();
329 | }
330 |
331 | public String getProductModel(int productIndex) {
332 |
333 | String xpath = "//table[contains(@class,'table table-bordered table-hover')]/tbody/tr[" + productIndex + "]//td[3]";
334 | return WaitUtils.waitForVisibility(this.driver, driver.findElement(By.xpath(xpath))).getText();
335 | }
336 |
337 | public String getProductUnitPrice(int productIndex) {
338 |
339 | String xpath = "//table[contains(@class,'table table-bordered table-hover')]/tbody/tr[" + productIndex + "]//td[5]/div[contains(@class,'price')]";
340 | return WaitUtils.waitForVisibility(this.driver, driver.findElement(By.xpath(xpath))).getText();
341 | }
342 |
343 | public ShoppingCart addToShoppingCart(int productIndex) {
344 | String xpath = "//table[contains(@class,'table table-bordered table-hover')]/tbody/tr[" + productIndex + "]//td[6]//button[contains(@data-original-title,'Add to Cart')]";
345 | click(this.driver.findElement(By.xpath(xpath)));
346 | TestLog.stepInfo("Adding product to shopping cart at Index: " + productIndex);
347 | return new ShoppingCart(driver);
348 |
349 | }
350 |
351 | public void removeFromWishList(int productIndex) {
352 |
353 | String xpath = "//table[contains(@class,'table table-bordered table-hover')]/tbody/tr[" + productIndex + "]//td[6]//a[contains(@data-original-title,'Remove')]";
354 | click(this.driver.findElement(By.xpath(xpath)));
355 | TestLog.stepInfo("Product at Index " + productIndex + " Removed From WishList");
356 |
357 | }
358 |
359 | public boolean isAvailable(int productIndex) {
360 |
361 | String xpath = "//table[contains(@class,'table table-bordered table-hover')]/tbody/tr[" + productIndex + "]//td[4]";
362 | String productAvailability = WaitUtils.waitForVisibility(this.driver, driver.findElement(By.xpath(xpath))).getText();
363 |
364 | Map map = Map.of(
365 | "Out Of Stock", false,
366 | "In Stock", true
367 | );
368 | return map.get(productAvailability);
369 | }
370 |
371 |
372 | public Account navigateToAccountPage() {
373 |
374 | WaitUtils.waitForClickable(driver, continueBtn).click();
375 | return new Account(driver);
376 | }
377 |
378 | public ShoppingCart navigateToCartPage() {
379 |
380 | WaitUtils.waitForClickable(driver, shoppingCartBtn).click();
381 | return new ShoppingCart(driver);
382 | }
383 |
384 |
385 | }
386 | }
387 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/pages/HomePage.java:
--------------------------------------------------------------------------------
1 | package com.framework.pages;
2 |
3 | import com.framework.factory.Constant;
4 | import com.framework.base.BasePage;
5 | import com.framework.reporting.TestLog;
6 | import com.framework.utils.WaitUtils;
7 | import org.openqa.selenium.By;
8 | import org.openqa.selenium.JavascriptExecutor;
9 | import org.openqa.selenium.WebDriver;
10 | import org.openqa.selenium.WebElement;
11 | import org.openqa.selenium.support.FindBy;
12 | import org.openqa.selenium.support.PageFactory;
13 | import org.openqa.selenium.support.ui.ExpectedConditions;
14 |
15 | import java.util.List;
16 |
17 | public class HomePage extends BasePage {
18 |
19 | public HomePage(WebDriver driver) {
20 | super(driver);
21 | PageFactory.initElements(driver, this);
22 |
23 | }
24 |
25 | @FindBy(xpath = "//img[@title='naveenopencart']")
26 | private WebElement pageLogo;
27 |
28 | @FindBy(name = "search")
29 | private WebElement searchBar;
30 |
31 | @FindBy(className = "swiper-button-prev")
32 | private WebElement prev;
33 |
34 | @FindBy(className = "swiper-button-next")
35 | private WebElement next;
36 |
37 | @FindBy(xpath = "//span[text()='Currency']")
38 | private WebElement currencyDropDown;
39 |
40 | @FindBy(xpath = "//button[text()='£ Pound Sterling']")
41 | private WebElement pound;
42 |
43 | @FindBy(xpath = "//button[text()='$ US Dollar']")
44 | private WebElement dollar;
45 |
46 | @FindBy(xpath = "//button[text()='€ Euro']")
47 | private WebElement euro;
48 |
49 | @FindBy(xpath = "//span[@id='cart-total' and contains(text(), '0.00€')]")
50 | private WebElement verifyEuro;
51 |
52 | @FindBy(xpath = "//span[@id='cart-total' and contains(text(), '$0.00')]")
53 | private WebElement verifyDollar;
54 |
55 | @FindBy(xpath = "//span[@id='cart-total' and contains(text(), '£0.00')]")
56 | private WebElement verifyPound;
57 |
58 | @FindBy(xpath = "//i[@class='fa fa-search']")
59 | private WebElement searchIcon;
60 |
61 | @FindBy(className = "img-responsive")
62 | private WebElement banners;
63 |
64 | @FindBy(xpath = "//span[text()='123456789']")
65 | private WebElement mobileContact;
66 |
67 | @FindBy(xpath = "//a[@title='My Account']")
68 | private WebElement accountHeader;
69 |
70 | @FindBy(xpath = "//a[@id='wishlist-total']")
71 | private WebElement wishList;
72 |
73 | By wishListByLocators = By.id("wishlist-total");
74 |
75 | @FindBy(xpath = "//a[@title='Shopping Cart']")
76 | private WebElement shoppingCart;
77 |
78 | @FindBy(xpath = "//a[@title='Shopping Cart']")
79 | private WebElement checkOut;
80 |
81 | @FindBy(xpath = "//li//a[@href='https://naveenautomationlabs.com/opencart/index.php?route=account/register' and contains(text(),'Register')]")
82 | private WebElement registerLink;
83 |
84 | @FindBy(xpath = "//li//a[@href='https://naveenautomationlabs.com/opencart/index.php?route=account/login']")
85 | private WebElement login;
86 |
87 | @FindBy(xpath = "//a[@title='My Account']")
88 | private WebElement myAccount;
89 |
90 | @FindBy(xpath = "//a[text()='Order History']")
91 | private WebElement orderHistory;
92 |
93 | @FindBy(xpath = "//a[contains(@title,'Transactions')]")
94 | private WebElement transaction;
95 |
96 | @FindBy(xpath = "//a[contains(@title,'Downloads')]")
97 | private WebElement downloads;
98 |
99 | @FindBy(xpath = "//a[contains(@title,'Logout')]")
100 | private WebElement logout;
101 |
102 | @FindBy(xpath = "//button[contains(@class, 'btn') and .//span[@id='cart-total']]")
103 | private WebElement cartItems;
104 |
105 | @FindBy(xpath = "//p[text()='Your shopping cart is empty!']")
106 | private WebElement emptyCartMsg;
107 |
108 |
109 | public void goTo() {
110 | this.driver.get(Constant.BASE_URL);
111 | this.driver.manage().window().maximize();
112 | JavascriptExecutor js = (JavascriptExecutor) driver;
113 | js.executeScript("window.scrollTo(0, 0);");
114 | }
115 |
116 | @FindBy(xpath = "//div[@id='content']//div[@class='row']/div")
117 | private List listOfFeaturedProducts;
118 |
119 | @FindBy(xpath = "//a[text()='Desktops']")
120 | private WebElement desktops;
121 |
122 | @FindBy(xpath = "//a[text()='Laptops & Notebooks']")
123 | private WebElement laptopAndDesktops;
124 |
125 | @FindBy(xpath = "//a[text()='Components']")
126 | private WebElement components;
127 |
128 | @FindBy(xpath = "//a[text()='Tablets']")
129 | private WebElement tablets;
130 |
131 | @FindBy(xpath = "//a[text()='Software']")
132 | private WebElement software;
133 |
134 | @FindBy(xpath = "//a[text()='Phones & PDAs']")
135 | private WebElement phoneAndPDAs;
136 |
137 | @FindBy(xpath = "//a[text()='Cameras']")
138 | private WebElement cameras;
139 |
140 | @FindBy(xpath = "//a[text()='MP3 Players']")
141 | private WebElement mp3Players;
142 |
143 |
144 | public Register navigateToRegistrationPage() {
145 |
146 | click(myAccount);
147 | click(registerLink);
148 | return new Register(driver);
149 |
150 | }
151 |
152 | public Account.WishList navigateToWishListPage() {
153 |
154 | click(wishList);
155 | return new Account.WishList(this.driver);
156 | }
157 |
158 | public Login navigateToLoginPage() {
159 | click(myAccount);
160 | click(login);
161 | return new Login(driver);
162 | }
163 |
164 | public ShoppingCart navigateToShoppingCartPage() {
165 | click(myAccount);
166 | click(shoppingCart);
167 | return new ShoppingCart(driver);
168 | }
169 |
170 | public String returnCartItem() {
171 | return WaitUtils.waitForClickable(driver, cartItems).getText();
172 | }
173 |
174 | public String returnWishListItem() {
175 |
176 | return WaitUtils.waitForClickable(driver, wishList).getText();
177 |
178 | }
179 |
180 | public boolean isPageLogoDisplayed() {
181 | return WaitUtils.waitForVisibility(driver, pageLogo).isDisplayed();
182 | }
183 |
184 | public boolean isMyAccountEnabled() {
185 | return WaitUtils.waitForVisibility(driver, myAccount).isEnabled();
186 | }
187 |
188 | public boolean isWishListEnabled() {
189 | return WaitUtils.waitForVisibility(driver, wishList).isDisplayed();
190 | }
191 |
192 | public boolean isSearchBarEnabled() {
193 | return WaitUtils.waitForVisibility(driver, searchBar).isEnabled();
194 | }
195 |
196 | public boolean isSearchIconEnabled() {
197 | return WaitUtils.waitForVisibility(driver, searchIcon).isEnabled();
198 | }
199 |
200 | public String verifyCurrency(String currency) {
201 |
202 | click(currencyDropDown);
203 |
204 | return switch (currency.toLowerCase()) {
205 | case "pound" -> {
206 | click(pound);
207 | yield verifyPound.getText();
208 | }
209 | case "dollar" -> {
210 | click(dollar);
211 | ;
212 | yield verifyDollar.getText();
213 | }
214 | case "euro" -> {
215 | click(euro);
216 | yield verifyEuro.getText();
217 | }
218 | default -> throw new RuntimeException("Currency Not Supported ::" + currency);
219 | };
220 |
221 |
222 | }
223 |
224 | private By locateProductByIndex(int productIndex, String productFeature) {
225 | if (productFeature.equalsIgnoreCase("AddToCart")) {
226 | return By.xpath("//div[@id='content']//div[@class='row']/div[" + productIndex + "]/div[1]/div[3]//button[1]");
227 | } else if (productFeature.equalsIgnoreCase("AddToWishList")) {
228 | return By.xpath("//div[@id='content']//div[@class='row']/div[" + productIndex + "]/div[1]/div[3]//button[@data-original-title='Add to Wish List']");
229 | } else
230 | return By.xpath("//div[@id='content']//div[@class='row']/div[" + productIndex + "]/div[1]/div[3]//button[@data-original-title='Compare this Product']");
231 |
232 | }
233 |
234 | private By locateProductByName(String productName, String productFeature) {
235 | if (productFeature.equalsIgnoreCase("AddToCart")) {
236 | return By.xpath("//h4/a[contains(text(),'" + productName + "')]/ancestor::div[@class='product-thumb transition']//button//span[contains(text(), 'Add to Cart')]");
237 | } else if (productFeature.equalsIgnoreCase("AddToWishList")) {
238 | return By.xpath("//h4/a[contains(text(),'" + productName + "')]/ancestor::div[@class='product-thumb transition']//button[@data-original-title='Add to Wish List']");
239 | }
240 | return By.xpath("");
241 | }
242 |
243 | public void addToCartByIndex(int productIndex) {
244 | if (productIndex > 4 || productIndex < 1) {
245 | throw new RuntimeException("Product Index Out Of Range ❌");
246 | }
247 | WaitUtils.waitForClickable(driver, this.driver.findElement(locateProductByIndex(productIndex, "AddToCart"))).click();
248 | TestLog.stepInfo(" ✅ Product at index " + productIndex + " is Successfully Added to Cart");
249 | }
250 |
251 | public void addToCartByProductName(String productName) {
252 | try {
253 | WaitUtils.waitForClickable(driver, this.driver.findElement(locateProductByName(productName, "AddToCart"))).click();
254 | TestLog.stepInfo(productName + " is Successfully Added to Cart ✅");
255 | } catch (Exception e) {
256 | throw new RuntimeException("Product With Name " + productName + " Not Found ❌");
257 | }
258 |
259 | }
260 |
261 | public void addToWishListByIndex(int productIndex) {
262 | if (productIndex > 4 || productIndex < 1) {
263 | throw new RuntimeException("Product Index Out Of Range ❌");
264 | }
265 | WaitUtils.waitForClickable(driver, this.driver.findElement(locateProductByIndex(productIndex, "AddToWishList"))).click();
266 | TestLog.stepInfo("✅Product at index " + productIndex + " is Successfully Added to Wish List");
267 | }
268 |
269 | public void addToWishListByProductName(String productName) {
270 | try {
271 | WaitUtils.waitForClickable(driver, this.driver.findElement(locateProductByName(productName, "AddToWishList"))).click();
272 | TestLog.stepInfo(productName + " is Successfully Added to Wish List ✅");
273 | } catch (Exception e) {
274 | throw new RuntimeException("Product With Name " + productName + " Not Found ❌");
275 | }
276 |
277 | }
278 |
279 | public Search searchProduct(String productName) {
280 |
281 | enterText(searchBar, productName);
282 | searchIcon.click();
283 | TestLog.stepInfo("Search Page Title Is ::::" + this.driver.getTitle());
284 | return new Search(driver);
285 | }
286 |
287 | public void validatePages(){
288 |
289 | WaitUtils.waitFor(ExpectedConditions.elementToBeClickable(searchBar),this.driver,5);
290 | }
291 |
292 |
293 | }
294 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/pages/Login.java:
--------------------------------------------------------------------------------
1 | package com.framework.pages;
2 |
3 | import com.framework.base.BasePage;
4 | import com.framework.utils.WaitUtils;
5 | import org.openqa.selenium.WebDriver;
6 | import org.openqa.selenium.WebElement;
7 | import org.openqa.selenium.support.FindBy;
8 | import org.openqa.selenium.support.PageFactory;
9 |
10 | public class Login extends BasePage {
11 |
12 | public Login(WebDriver driver) {
13 | super(driver);
14 | PageFactory.initElements(driver, this);
15 | }
16 |
17 | @FindBy(xpath = "//a[text()='Continue']")
18 | private WebElement clickToCreateNewUser;
19 |
20 | @FindBy(id = "input-email")
21 | private WebElement email;
22 |
23 | @FindBy(id = "input-password")
24 | private WebElement password;
25 |
26 | @FindBy(xpath = "//input[@class='btn btn-primary']")
27 | private WebElement loginButton;
28 |
29 | @FindBy(xpath = "//a[text()='Forgotten Password']")
30 | private WebElement forgotPwd;
31 |
32 | @FindBy(xpath="//div[@class=\"alert alert-danger alert-dismissible\"]")
33 | private WebElement invalidUserAlert;
34 |
35 | public Account loginAsExistingUser(String userName, String pwd) {
36 |
37 | enterText(email,userName);
38 | enterText(password,pwd);
39 | click(loginButton);
40 | return new Account(driver);
41 | }
42 |
43 | public String invalidUser(){
44 | return WaitUtils.waitForVisibility(driver,invalidUserAlert).getText();
45 | }
46 |
47 |
48 |
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/pages/Register.java:
--------------------------------------------------------------------------------
1 | package com.framework.pages;
2 |
3 | import com.framework.base.BasePage;
4 | import com.framework.utils.WaitUtils;
5 | import org.openqa.selenium.WebDriver;
6 | import org.openqa.selenium.WebElement;
7 | import org.openqa.selenium.support.FindBy;
8 | import org.openqa.selenium.support.PageFactory;
9 |
10 | public class Register extends BasePage {
11 |
12 | public Register(WebDriver driver) {
13 | super(driver);
14 | PageFactory.initElements(driver, this);
15 | }
16 |
17 | @FindBy(id = "input-firstname")
18 | private WebElement firstName;
19 |
20 | @FindBy(id = "input-lastname")
21 | private WebElement lastName;
22 |
23 | @FindBy(id = "input-email")
24 | private WebElement email;
25 |
26 | @FindBy(id = "input-telephone")
27 | private WebElement telphone;
28 |
29 | @FindBy(id = "input-password")
30 | private WebElement pwd;
31 |
32 | @FindBy(id = "input-confirm")
33 | private WebElement cnfrmPwd;
34 |
35 | @FindBy(xpath = "//label[@class='radio-inline']/input[@name='newsletter' and @value='1']")
36 | private WebElement yesSubs;
37 |
38 | @FindBy(xpath = "//label[@class='radio-inline']/input[@name='newsletter' and @value='0']")
39 | private WebElement noSubs;
40 |
41 | @FindBy(xpath = "//input[contains(@name,'agree')]")
42 | private WebElement agreeAgreement;
43 |
44 | @FindBy(xpath = "//input[contains(@value,'Continue')]")
45 | private WebElement continueButton;
46 |
47 | @FindBy(xpath = "//div[contains(text(), 'Warning')]")
48 | private WebElement warningMsg;
49 |
50 |
51 | @FindBy(xpath = "//div[contains(@class, 'alert-danger') and contains(text(), 'Warning')]")
52 | private WebElement emailRegWarningMsg;
53 |
54 | @FindBy(xpath = "//a[contains(text(), 'login page')]")
55 | private WebElement loginLink;
56 |
57 | public Login navigateToLoginPage() {
58 |
59 | WaitUtils.waitForClickable(driver, loginLink).click();
60 | return new Login(driver);
61 | }
62 |
63 | public boolean isWarningMsgPresent() {
64 |
65 | return WaitUtils.waitForVisibility(driver, warningMsg).isDisplayed();
66 | }
67 |
68 | public boolean isEmailRegWarningMsgPresent() {
69 |
70 | return WaitUtils.waitForVisibility(driver, emailRegWarningMsg).isDisplayed();
71 | }
72 |
73 | public Account.Success registerNewUser(String firstNameValue, String lastNameValue, String emailValue,
74 | String telephoneValue, String pwdValue, String confirmPwdValue) {
75 |
76 | enterText(firstName, firstNameValue);
77 | enterText(lastName, lastNameValue);
78 | enterText(email, emailValue);
79 | enterText(telphone, telephoneValue);
80 | enterText(pwd, pwdValue);
81 | enterText(cnfrmPwd, confirmPwdValue);
82 |
83 | clickElement(noSubs);
84 | clickElement(agreeAgreement);
85 | clickElement(continueButton);
86 |
87 | return new Account.Success(driver);
88 | }
89 |
90 | private void clickElement(WebElement element) {
91 | click(element);
92 | }
93 |
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/pages/Search.java:
--------------------------------------------------------------------------------
1 | package com.framework.pages;
2 |
3 | import com.framework.base.BasePage;
4 |
5 | import com.framework.utils.WaitUtils;
6 | import lombok.Getter;
7 | import org.openqa.selenium.By;
8 | import org.openqa.selenium.NoSuchElementException;
9 | import org.openqa.selenium.WebDriver;
10 | import org.openqa.selenium.WebElement;
11 | import org.openqa.selenium.support.FindBy;
12 | import org.openqa.selenium.support.PageFactory;
13 | import org.openqa.selenium.support.ui.Select;
14 |
15 | import java.util.List;
16 |
17 | public class Search extends BasePage {
18 |
19 | public Search(WebDriver driver) {
20 | super(driver);
21 | PageFactory.initElements(driver, this);
22 | }
23 |
24 | @FindBy(xpath = "//input[@id='input-search']")
25 | private WebElement searchCriteria;
26 |
27 | @FindBy(xpath = "//input[@id='button-search']")
28 | private WebElement searchBtn;
29 |
30 | @FindBy(xpath = "//button[@id='list-view']")
31 | private WebElement listView;
32 |
33 | @FindBy(xpath = "//button[@id='grid-view']")
34 | private WebElement gridView;
35 |
36 | @FindBy(xpath = "//select[@id='input-sort']")
37 | private WebElement sortBy;
38 |
39 | @FindBy(xpath = "//select[@name='category_id']")
40 | private WebElement searchCategory;
41 |
42 | @FindBy(xpath="//p[text()='There is no product that matches the search criteria.']")
43 | private WebElement noProductFound;
44 |
45 | @Getter
46 | @FindBy(xpath = "//div[@id='content']/div[3]/div")
47 | private List noOfProduct;
48 |
49 | @FindBy(xpath = "//a[@id='wishlist-total']")
50 | private WebElement wishList;
51 |
52 | @FindBy(xpath = "//a[@title='Shopping Cart']")
53 | private WebElement shoppingCart;
54 |
55 | public String getProductName(int productIndex) {
56 |
57 | String productName = "//div[@id='content']/div[3]/div[" + productIndex + "]//div[2]//a";
58 |
59 | return WaitUtils.waitForVisibility(driver, driver.findElement(By.xpath(productName))).getText();
60 |
61 | }
62 |
63 | public void addToCart(int productIndex) {
64 |
65 | String addToCart = "//div[@id='content']/div[3]/div[" + productIndex + "]//div[2]//div[2]//span[contains(text(),'Add to Cart')]";
66 |
67 | WaitUtils.waitForVisibility(driver, driver.findElement(By.xpath(addToCart))).click();
68 |
69 | }
70 |
71 | public void addToWishList(int productIndex) {
72 |
73 | try{
74 | String addToWishList = "//div[@id='content']/div[3]/div[" + productIndex + "]//div[2]//div[2]//button[contains(@data-original-title,'Add to Wish List')]";
75 | WaitUtils.waitForVisibility(driver, driver.findElement(By.xpath(addToWishList))).click();
76 | } catch (NoSuchElementException e) {
77 | throw new RuntimeException("Product At Index " + productIndex + " Not Found ❌");
78 | }
79 |
80 | }
81 |
82 | public String getProductPrice(int productIndex) {
83 |
84 | String price = "//div[@id='content']/div[3]/div[" + productIndex + "]//div[2]//div[1]//p[2][@class='price']";
85 |
86 | return WaitUtils.waitForVisibility(driver, driver.findElement(By.xpath(price))).getText();
87 | }
88 |
89 | public String getProductFeature(int productIndex) {
90 |
91 | String productFeature = "//div[@id='content']/div[3]/div[" + productIndex + "]//div[2]//div[1]/p[1]";
92 |
93 | return WaitUtils.waitForVisibility(driver, driver.findElement(By.xpath(productFeature))).getText();
94 | }
95 |
96 | public void getGridView() {
97 |
98 | WaitUtils.waitForVisibility(driver, gridView).click();
99 | }
100 |
101 | public void getListView() {
102 |
103 | WaitUtils.waitForVisibility(driver, listView).click();
104 | }
105 |
106 | public boolean isNoProductFound(){
107 |
108 | return (WaitUtils.waitForVisibility(this.driver,noProductFound).isDisplayed()) ;
109 | }
110 |
111 |
112 | public void sortProductByPriceHighToLow(){
113 |
114 | searchFromDropdownByText(sortBy,"Price (High > Low)");
115 | }
116 |
117 | public void sortProductByPriceLowToHigh(){
118 |
119 | searchFromDropdownByText(sortBy,"Price (Low > High)");
120 | }
121 |
122 | public void sortProductByRatingLowToHigh(){
123 |
124 | searchFromDropdownByText(sortBy,"Rating (Lowest)");
125 | }
126 |
127 | public void sortProductByRatingHighToLow(){
128 |
129 | searchFromDropdownByText(sortBy,"Rating (Highest)");
130 | }
131 |
132 | public void sortProductByNameA2Z(){
133 |
134 | searchFromDropdownByText(sortBy,"Name (A - Z)");
135 | }
136 |
137 | public void sortProductByNameZ2A(){
138 |
139 | searchFromDropdownByText(sortBy,"Name (Z - A)");
140 | }
141 |
142 | public Account.WishList navigateToWishListPage(){
143 |
144 | WaitUtils.waitForVisibility(driver,wishList).click();
145 | return new Account.WishList(driver);
146 | }
147 |
148 | public ShoppingCart navigateToCartPage(){
149 |
150 | WaitUtils.waitForVisibility(driver,shoppingCart).click();
151 | return new ShoppingCart(driver);
152 | }
153 |
154 |
155 |
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/pages/ShoppingCart.java:
--------------------------------------------------------------------------------
1 | package com.framework.pages;
2 |
3 | import com.framework.base.BasePage;
4 | import com.framework.reporting.TestLog;
5 | import com.framework.utils.WaitUtils;
6 | import lombok.Getter;
7 | import org.openqa.selenium.By;
8 | import org.openqa.selenium.WebDriver;
9 | import org.openqa.selenium.WebElement;
10 | import org.openqa.selenium.support.FindBy;
11 | import org.openqa.selenium.support.PageFactory;
12 |
13 | import java.util.List;
14 |
15 |
16 | public class ShoppingCart extends BasePage {
17 |
18 | public ShoppingCart(WebDriver driver) {
19 | super(driver);
20 | PageFactory.initElements(driver, this);
21 |
22 | }
23 |
24 | @FindBy(xpath = "//a[text()='Shopping Cart']")
25 | private WebElement pageHeader;
26 |
27 | @FindBy(xpath = "//div[@class='col-sm-12']//p[text()='Your shopping cart is empty!']")
28 | private WebElement emptyCartMessage;
29 |
30 | @FindBy(xpath = "//a[contains(text(), 'Continue Shopping')]")
31 | private WebElement continueShopping;
32 |
33 | @FindBy(xpath = "//a[contains(text(), 'Checkout')]")
34 | private WebElement checkout;
35 |
36 | @Getter
37 | @FindBy(xpath = "//div[@class='table-responsive']/table/tbody/tr")
38 | List shoppingCartItems;
39 |
40 | @FindBy(xpath = "//td[@class='text-right' and strong[text()='Total:']]/ancestor::tr/td[2]")
41 | private WebElement finalPriceOfCart;
42 |
43 | @FindBy(xpath = "//div[@class='alert alert-success alert-dismissible' and contains(text(), 'You have modified your shopping cart')]")
44 | private WebElement modifyShoppingCartMsg;
45 |
46 | public String finalPriceOfCart() {
47 |
48 | String xpath="//td[@class='text-right' and strong[text()='Total:']]/ancestor::tr/td[2]";
49 | WebElement finalPriceOfCart = this.driver.findElement(By.xpath(xpath));
50 | return finalPriceOfCart.getText();
51 | }
52 |
53 | public String getProductName(int productIndex) {
54 |
55 | String xpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[2]/a";
56 | WebElement webElement = this.driver.findElement(By.xpath(xpath));
57 | return webElement.getText();
58 |
59 | }
60 |
61 | public boolean emptyShoppingCartMessage() {
62 |
63 | return WaitUtils.waitForVisibility(this.driver, emptyCartMessage).isDisplayed();
64 | }
65 |
66 | public boolean modifyShoppingCartMessage() {
67 |
68 | return WaitUtils.waitForVisibility(this.driver, modifyShoppingCartMsg).isDisplayed();
69 | }
70 |
71 | public String getProductModel(int productIndex) {
72 |
73 | String xpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[3]";
74 | WebElement webElement = this.driver.findElement(By.xpath(xpath));
75 | return WaitUtils.waitForVisibility(this.driver, webElement).getText();
76 |
77 |
78 | }
79 |
80 | public int getQuantityOfProduct(int productIndex) {
81 |
82 | String xpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[4]//input";
83 | WebElement webElement = this.driver.findElement(By.xpath(xpath));
84 | return Integer.parseInt(WaitUtils.waitForVisibility(this.driver, webElement).getAttribute("value"));
85 | }
86 |
87 | public void updateQuantityOfProduct(int productIndex, String quantity) {
88 |
89 | String xpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[4]//input";
90 | WebElement webElement = this.driver.findElement(By.xpath(xpath));
91 | enterText(WaitUtils.waitForClickable(this.driver, webElement), quantity);
92 | TestLog.stepInfo("Quantity of Product At Index " + productIndex + " is updated");
93 |
94 | }
95 |
96 | public void refreshProductQuantity(int productIndex) {
97 |
98 | String xpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[4]//button[1][contains(@class, 'btn-primary') and @data-original-title='Update']";
99 | WebElement webElement = this.driver.findElement(By.xpath(xpath));
100 | click(webElement);
101 | }
102 |
103 | public void removeFromCartByIndex(int productIndex) {
104 | String productXpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[2]/a";
105 | String productName = this.driver.findElement(By.xpath(productXpath)).getText();
106 | String xpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[4]//button[2][contains(@class, 'btn btn-danger') and @data-original-title='Remove']";
107 | WebElement webElement = this.driver.findElement(By.xpath(xpath));
108 | click(webElement);
109 |
110 | TestLog.stepInfo(productName + " Successfully Removed from Shopping Cart ");
111 | }
112 |
113 | public String getProductPrice(int productIndex) {
114 |
115 | String xpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[5]";
116 | WebElement webElement = this.driver.findElement(By.xpath(xpath));
117 | return WaitUtils.waitForVisibility(this.driver, webElement).getText();
118 | }
119 |
120 | public String getTotalProductPrice(int productIndex) {
121 |
122 | String xpath = "//div[@class='table-responsive']/table/tbody/tr[" + productIndex + "]//td[6]";
123 | WebElement webElement = this.driver.findElement(By.xpath(xpath));
124 | return WaitUtils.waitForVisibility(this.driver, webElement).getText();
125 | }
126 |
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/reporting/TestLog.java:
--------------------------------------------------------------------------------
1 | package com.framework.reporting;
2 |
3 |
4 | import org.apache.log4j.Logger;
5 | import org.apache.log4j.PropertyConfigurator;
6 | import org.testng.Reporter;
7 |
8 | import java.awt.*;
9 |
10 | public class TestLog {
11 |
12 | static Logger logger = Logger.getLogger(TestLog.class.getName());
13 |
14 | static {
15 | //PropertyConfigurator.configure("src/main/resources/log4j.properties");
16 |
17 | PropertyConfigurator.configure(System.getProperty("user.dir")+"/src/main/resources/log4j.properties");
18 | }
19 |
20 | public static void stepInfo(String message) {
21 | logger.info(message);
22 | Reporter.log(message);
23 | }
24 |
25 | public static void stepInfoInGreenColor(String message) {
26 | String foncolor = Color.GREEN.toString();
27 | logger.info(message);
28 | Reporter.log("" + message + "");
29 | }
30 |
31 | public static void testFail(String message) {
32 | logger.error(message);
33 | }
34 |
35 | public static void testPass(String message) {
36 | logger.info(message);
37 | }
38 |
39 | public static void testStart(String message, String desc) {
40 | logger.info(message);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/utils/ScreenshotUtil.java:
--------------------------------------------------------------------------------
1 | package com.framework.utils;
2 |
3 |
4 | import com.framework.reporting.TestLog;
5 | import org.openqa.selenium.OutputType;
6 | import org.openqa.selenium.TakesScreenshot;
7 | import org.openqa.selenium.WebDriver;
8 | import org.openqa.selenium.io.FileHandler;
9 |
10 | import java.io.File;
11 | import java.io.IOException;
12 |
13 | public class ScreenshotUtil {
14 |
15 |
16 | public static void captureScreenshot(WebDriver driver, String testName) {
17 | File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
18 | String path = System.getProperty("user.dir") + "/src/test/resources/screenshots/" + testName + "_" + System.currentTimeMillis() + ".png";
19 | try {
20 | FileHandler.copy(src, new File(path));
21 | TestLog.stepInfo("Screenshot saved at: " + path);
22 | } catch (IOException e) {
23 | TestLog.stepInfo("Screenshot capture failed: " + e.getMessage());
24 | }
25 | }
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/framework/utils/WaitUtils.java:
--------------------------------------------------------------------------------
1 | package com.framework.utils;
2 |
3 | import org.openqa.selenium.WebDriver;
4 | import org.openqa.selenium.WebElement;
5 | import org.openqa.selenium.support.ui.*;
6 | import org.openqa.selenium.*;
7 |
8 | import java.time.Duration;
9 |
10 | import java.time.Duration;
11 | import java.util.List;
12 |
13 | public class WaitUtils {
14 |
15 | private static final int DEFAULT_TIMEOUT = 50;
16 |
17 |
18 | public static WebElement waitForVisibility(WebDriver driver, WebElement element) {
19 | return new WebDriverWait(driver, Duration.ofSeconds(DEFAULT_TIMEOUT))
20 | .until(ExpectedConditions.visibilityOf(element));
21 | }
22 |
23 | public static WebElement waitForClickable(WebDriver driver, WebElement element) {
24 | return new WebDriverWait(driver, Duration.ofSeconds(DEFAULT_TIMEOUT))
25 | .until(ExpectedConditions.elementToBeClickable(element));
26 | }
27 |
28 | public static WebElement fluentWait(WebDriver driver, By locator, int timeoutSec, int pollingSec) {
29 | Wait wait = new FluentWait<>(driver)
30 | .withTimeout(Duration.ofSeconds(timeoutSec))
31 | .pollingEvery(Duration.ofSeconds(pollingSec))
32 | .ignoring(NoSuchElementException.class)
33 | .ignoring(StaleElementReferenceException.class);
34 |
35 | return wait.until(webDriver -> webDriver.findElement(locator)); // avoid shadowing 'driver'
36 | }
37 |
38 | public static T waitFor(ExpectedCondition condition, WebDriver driver, int timeoutInSeconds) {
39 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(timeoutInSeconds));
40 | return wait.until(condition);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | #Application Logs
2 | log4j.rootLogger=INFO, stdout, dest1
3 | //log4j.rootLogger=DEBUG, DebugAppender
4 | log4j.logger.org.apache.http=OFF
5 | # Redirect log messages to console
6 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
7 | log4j.appender.stdout.Target=System.out
8 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.stdout.layout.ConversionPattern=%d{dd-MM-yyyy HH:mm:ss} %-5p %c{1}:%L - %m%n
10 | # Redirect messages to log file
11 | log4j.appender.dest1=org.apache.log4j.RollingFileAppender
12 | log4j.appender.dest1.maxFileSize=5000KB
13 | log4j.appender.dest1.maxBackupIndex=3
14 | log4j.appender.dest1.layout=org.apache.log4j.PatternLayout
15 | log4j.appender.dest1.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %c %m%n
16 | log4j.appender.dest1.File=./logs/Application.log
17 | #do not append the old file. Create a new log file everytime
18 | log4j.appender.dest1.Append=false
--------------------------------------------------------------------------------
/src/test/java/com/base/BaseTest.java:
--------------------------------------------------------------------------------
1 | package com.base;
2 |
3 | import com.framework.exceptions.PageLoadException;
4 | import com.framework.factory.Constant;
5 | import com.framework.pages.Account;
6 | import com.framework.pages.HomePage;
7 | import com.framework.pages.Register;
8 | import com.framework.reporting.TestLog;
9 | import com.framework.utils.ScreenshotUtil;
10 | import com.google.common.util.concurrent.Uninterruptibles;
11 | import com.framework.factory.DriverFactory;
12 | import org.openqa.selenium.WebDriver;
13 | import org.testng.Assert;
14 | import org.testng.ITestResult;
15 | import org.testng.annotations.AfterMethod;
16 | import org.testng.annotations.AfterTest;
17 | import org.testng.annotations.BeforeMethod;
18 | import org.testng.annotations.BeforeTest;
19 |
20 | import java.util.Map;
21 | import java.util.concurrent.TimeUnit;
22 |
23 | public class BaseTest {
24 |
25 | public WebDriver driver;
26 |
27 |
28 | @BeforeMethod
29 | public void setUpDriver() {
30 | this.driver = DriverFactory.getDriver("firefox"); //Get The Name of Browser from either config files or as JENKINS Input
31 | TestLog.stepInfo("Chrome Driver Set Up Completed");
32 |
33 | }
34 |
35 | @AfterMethod
36 | public void quitDriver(ITestResult result) {
37 | Uninterruptibles.sleepUninterruptibly(3, TimeUnit.SECONDS);
38 | if (result.getStatus() == ITestResult.FAILURE) {
39 | ScreenshotUtil.captureScreenshot(driver, result.getName());
40 | }
41 | this.driver.quit();
42 | TestLog.stepInfo("Quit Driver Completed");
43 |
44 | }
45 |
46 | public void assertPageTitle(String actualTitle, String expectedTitle, String pageName) {
47 | Assert.assertEquals(actualTitle, expectedTitle, pageName + " title mismatch");
48 | TestLog.stepInfo("Title of the " + pageName + " is: " + actualTitle);
49 | }
50 |
51 | public HomePage launchHomePage() throws PageLoadException {
52 | try {
53 | HomePage homePage = new HomePage(driver);
54 | homePage.goTo();
55 | TestLog.stepInfo("✅ Home Page Opened Successfully");
56 | return homePage;
57 | } catch (Exception e) {
58 | String errorMsg = "❌ Failed to load Home Page: " + e.getMessage();
59 | TestLog.stepInfo(errorMsg);
60 | throw new PageLoadException(errorMsg, e);
61 | }
62 | }
63 |
64 | public Register goToRegisterUserPage() throws PageLoadException {
65 | HomePage homePage = goToHomePage();
66 | Register registerPage = homePage.navigateToRegistrationPage();
67 | assertPageTitle(registerPage.getTitle(driver), Constant.REGISTER_PAGE_TITLE, "Register Page");
68 | TestLog.stepInfo("Registration Page Opened");
69 | return new Register(driver);
70 | }
71 |
72 | public void verifyLogoutPageElements(Account.Logout logoutPage) {
73 | Assert.assertTrue(logoutPage.isAccountLogoutDisplayed(), "Account Log Out Field is not Displayed");
74 | Assert.assertTrue(logoutPage.isContinueBtnEnabled(), "Continue Button is not Enabled");
75 | Assert.assertTrue(logoutPage.isLogOffMsgDisplayed(), "Log Off Msg Field is not Displayed");
76 | Assert.assertTrue(logoutPage.isLogOutMsgDisplayed(), "Log Out Msg Field is not Displayed");
77 | assertPageTitle(logoutPage.getTitle(driver), Constant.LOGOUT_PAGE_TITLE, "Log Out Page");
78 | }
79 |
80 | public void verifyElement(boolean condition, String elementName) {
81 | Assert.assertTrue(condition, elementName + " is not present/enabled");
82 | TestLog.stepInfo(elementName + " is Present and Enabled/Displayed");
83 | }
84 |
85 | public int returnProductIndex(String productName) {
86 |
87 | Map map = Map.ofEntries(
88 | Map.entry("MacBook", 1),
89 | Map.entry("iPhone", 2),
90 | Map.entry("Apple Cinema 30", 3),
91 | Map.entry("Canon EOS 5D", 4)
92 | );
93 |
94 | return map.get(productName);
95 | }
96 |
97 | public HomePage goToHomePage() throws PageLoadException {
98 | HomePage homePage = launchHomePage();
99 | assertPageTitle(homePage.getTitle(driver), Constant.HOME_PAGE_TITLE, "Home Page");
100 | TestLog.stepInfo("User Is Logged In Successfully And on HomePage");
101 | return homePage;
102 | }
103 |
104 | public String priceExtractor(String priceText, String pricePattern) {
105 | if (priceText == null || priceText.trim().isEmpty()) {
106 | throw new IllegalArgumentException("Price text cannot be null or empty");
107 | }
108 | if (pricePattern == null || pricePattern.trim().isEmpty()) {
109 | throw new IllegalArgumentException("Price pattern cannot be null or empty");
110 | }
111 |
112 | try {
113 | java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(pricePattern);
114 | java.util.regex.Matcher matcher = pattern.matcher(priceText);
115 |
116 | if (matcher.find()) {
117 | String extractedPrice = matcher.group();
118 | TestLog.stepInfo("Successfully extracted price: " + extractedPrice);
119 | return extractedPrice;
120 | } else {
121 | TestLog.stepInfo("No price found in text: " + priceText);
122 | return "0.00";
123 | }
124 | } catch (java.util.regex.PatternSyntaxException e) {
125 | String errorMsg = "Invalid price pattern: " + e.getMessage();
126 | TestLog.stepInfo(errorMsg);
127 | throw new IllegalArgumentException(errorMsg, e);
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/account/RegistrationFlowTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.account;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.exceptions.PageLoadException;
5 | import com.framework.factory.Constant;
6 | import com.framework.pages.Account;
7 | import com.framework.pages.HomePage;
8 | import com.framework.pages.Login;
9 | import com.framework.pages.Register;
10 | import com.framework.reporting.TestLog;
11 | import io.qameta.allure.Description;
12 | import io.qameta.allure.Severity;
13 | import lombok.SneakyThrows;
14 | import org.testng.Assert;
15 | import org.testng.annotations.Test;
16 |
17 | import static io.qameta.allure.SeverityLevel.BLOCKER;
18 |
19 | public class RegistrationFlowTest extends BaseTest {
20 | HomePage homePage;
21 |
22 | @Test(groups = {"regression"})
23 | @Severity(BLOCKER)
24 | @Description("Verify If New Registrations are getting created")
25 | public void registerUser() throws PageLoadException {
26 | Register registerPage = goToRegisterUserPage();
27 | //Pick Data from Excel or JSON
28 | Account.Success myAccountSuccess = registerPage.registerNewUser("Suresh123", "Kumar123", "Suresh5123@gmail.com",
29 | "000765", "SureshUser123", "SureshUser123");
30 | assertPageTitle(myAccountSuccess.getTitle(driver), Constant.ACCOUNT_PAGE_SUCCESS_TITLE, "Accounts Success Page");
31 | myAccountSuccess.verifyAccountSuccessPageElements();
32 | TestLog.stepInfo("✅User is Successfully Registered and on Account Page");
33 | Account myAccount = myAccountSuccess.navigateToAccountPage();
34 | myAccount.verifyAccountPageElements();
35 | TestLog.stepInfo("My Account Page Elements Are Displayed and Enabled.");
36 | Account.Logout logoutPage = myAccount.logout();
37 | verifyLogoutPageElements(logoutPage);
38 | TestLog.stepInfo("✅User is Successfully Logged Out");
39 | homePage = logoutPage.navigateToHomePage();
40 | assertPageTitle(homePage.getTitle(driver), Constant.HOME_PAGE_TITLE, "Home Page");
41 | TestLog.stepInfo("✅ User is Successfully Logged Out and on Home Page");
42 | }
43 |
44 | @SneakyThrows
45 | @Test(groups = {"regression"})
46 | @Severity(BLOCKER)
47 | @Description("Create Account For Exiting User")
48 | public void createRegistrationForExistingUser() {
49 | Register registerPage = goToRegisterUserPage();
50 | registerPage.registerNewUser("Abhishek", "Kr", "abhishek007@gmail.com",
51 | "228877234", "Patna246", "Patna246");
52 | Assert.assertTrue(registerPage.isWarningMsgPresent(), "Warning Alert Msg is not displayed");
53 | Login loginPage = registerPage.navigateToLoginPage();
54 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
55 | TestLog.stepInfo("✅User is At Login Page");
56 | Account accountPage = loginPage.loginAsExistingUser("abhishek007@gmail.com", "Patna246");
57 | assertPageTitle(loginPage.getTitle(driver), Constant.ACCOUNT_PAGE_TITLE, "Account Page");
58 | TestLog.stepInfo("✅ Create Registration For Existing User Test Case Passed");
59 |
60 | }
61 |
62 | @SneakyThrows
63 | @Test(groups = {"regression"})
64 | @Severity(BLOCKER)
65 | @Description("Create Account With Already Registered User")
66 | public void registerForAlreadyRegisteredEmail() {
67 | Register registerPage = goToRegisterUserPage();
68 | registerPage.registerNewUser("", "K", "abhishek007@gmail.com",
69 | "", "", "");
70 | Assert.assertTrue(registerPage.isEmailRegWarningMsgPresent(), "Email Already Registered Alert Not Present.");
71 | assertPageTitle(registerPage.getTitle(driver), Constant.REGISTER_PAGE_TITLE, "Register Page");
72 |
73 | }
74 |
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/cart/AddToCartTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.cart;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.base.Product;
5 | import com.framework.exceptions.PageLoadException;
6 | import com.framework.factory.Constant;
7 | import com.framework.pages.HomePage;
8 | import com.framework.reporting.TestLog;
9 | import io.qameta.allure.Description;
10 | import io.qameta.allure.Severity;
11 | import org.testng.Assert;
12 | import org.testng.annotations.Test;
13 |
14 | import java.util.List;
15 |
16 | import static io.qameta.allure.SeverityLevel.BLOCKER;
17 |
18 | public class AddToCartTest extends BaseTest {
19 |
20 | @Test(groups = {"smoke"})
21 | @Severity(BLOCKER)
22 | @Description("Add The Product By Index")
23 | public void addProductToCartByIndex() throws PageLoadException {
24 | HomePage homePage = goToHomePage();
25 | //Using Builder Pattern to Pass Product Details
26 | Product product = Product.builder().productName("MacBook").
27 | productId("1").
28 | productPrice(602.00).
29 | build();
30 | homePage.addToCartByIndex(Integer.parseInt(product.getProductId()));
31 | String cartItemsDetails = homePage.returnCartItem();
32 | int noOfProductsInCart = Integer.parseInt(cartItemsDetails.split(" ")[0]);
33 | Assert.assertEquals(noOfProductsInCart, 1, "Number of products in Cart is wrong");
34 | TestLog.stepInfo("No of Products in Cart is " + noOfProductsInCart);
35 | String priceOfItemsInCart = homePage.returnCartItem().split("-")[1].replace(Constant.CURRENCY_DOLLAR,"");
36 | Assert.assertEquals(Double.parseDouble(priceOfItemsInCart), product.getProductPrice(), "Total price of items in Cart is wrong");
37 | TestLog.stepInfo("Price Of Products in Cart is " + priceOfItemsInCart);
38 |
39 |
40 | }
41 |
42 | @Test(groups={"smoke"})
43 | @Severity(BLOCKER)
44 | @Description("Add The Product By Name")
45 | public void addProductToCartByName() throws PageLoadException {
46 | setUpDriver();
47 | HomePage homePage = goToHomePage();
48 | //Using Builder Pattern to Pass Product Details
49 | Product product = Product.builder().productName("MacBook").
50 | productId("1").
51 | productPrice(602.00).
52 | build();
53 | homePage.addToCartByProductName(product.getProductName());
54 | String cartItemsDetails = homePage.returnCartItem();
55 | int noOfProductsInCart = Integer.parseInt(cartItemsDetails.split(" ")[0]);
56 | Assert.assertEquals(noOfProductsInCart, 1, "Number of products in Cart is wrong");
57 | TestLog.stepInfo("No of Products in Cart is " + noOfProductsInCart);
58 | String priceOfItemsInCart = homePage.returnCartItem().split("-")[1].replace(Constant.CURRENCY_DOLLAR,"");
59 | Assert.assertEquals(Double.parseDouble(priceOfItemsInCart), product.getProductPrice(), "Total price of items in Cart is wrong");
60 | TestLog.stepInfo("Price Of Products in Cart is " + priceOfItemsInCart);
61 |
62 |
63 | }
64 |
65 | @Test
66 | @Severity(BLOCKER)
67 | @Description("Add Multiple Products")
68 | public void addMultipleProducts() {
69 | HomePage homePage;
70 | try {
71 | homePage = goToHomePage();
72 | } catch (PageLoadException e) {
73 | throw new RuntimeException(e);
74 | }
75 | //Using Builder Pattern to Pass Product Details
76 |
77 |
78 | List productList = List.of(
79 | Product.builder().productName("MacBook").
80 | productId("1").
81 | productPrice(602.00).
82 | build(),
83 | Product.builder().productName("iPhone").
84 | productId("2").
85 | productPrice(123.20).
86 | build()
87 | );
88 | //Any no of products can be added in similar way.
89 |
90 | for (Product product : productList) {
91 | homePage.addToCartByIndex(Integer.parseInt(product.getProductId()));
92 | TestLog.stepInfo("First Product added is :: " + product.getProductName());
93 |
94 | }
95 | // Validate cart item count
96 | String cartItemsDetails = homePage.returnCartItem();
97 | double actualItemCount = Double.parseDouble(cartItemsDetails.split(" ")[0]);
98 | Assert.assertEquals(actualItemCount, productList.size(), "Number of products in Cart is wrong");
99 | TestLog.stepInfo("Number of Products in Cart: " + actualItemCount);
100 |
101 | String actualPriceText = homePage.returnCartItem().split("-")[1].replace(Constant.CURRENCY_DOLLAR, "").trim();
102 | double actualPrice = Double.parseDouble(actualPriceText);
103 |
104 | double expectedTotal = productList.stream().mapToDouble(Product::getProductPrice).sum();
105 | Assert.assertEquals(actualPrice, expectedTotal, "Total price of items in Cart is wrong");
106 | TestLog.stepInfo("Expected total price: $" + expectedTotal);
107 |
108 |
109 | }
110 |
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/cart/ModifyCartTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.cart;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.base.CommonMethods;
5 | import com.framework.base.Product;
6 | import com.framework.exceptions.PageLoadException;
7 | import com.framework.factory.Constant;
8 | import com.framework.pages.HomePage;
9 | import com.framework.pages.ShoppingCart;
10 | import com.framework.reporting.TestLog;
11 | import io.qameta.allure.Description;
12 | import io.qameta.allure.Severity;
13 | import org.testng.Assert;
14 | import org.testng.annotations.Test;
15 |
16 | import static io.qameta.allure.SeverityLevel.BLOCKER;
17 |
18 | public class ModifyCartTest extends BaseTest {
19 |
20 | @Test
21 | @Severity(BLOCKER)
22 | @Description("Modify Product Quantity In Cart")
23 | public void modifyCartProductByIndex() throws PageLoadException {
24 | HomePage homePage = goToHomePage();
25 | //Using Builder Pattern to Pass Product Details
26 | Product product = Product.builder().productName("MacBook").
27 | productId("1").
28 | productPrice(602.00).
29 | build();
30 | homePage.addToCartByIndex(Integer.parseInt(product.getProductId()));
31 | ShoppingCart shoppingCartPage = homePage.navigateToShoppingCartPage();
32 | assertPageTitle(shoppingCartPage.getTitle(driver), Constant.SHOPPING_CART_PAGE_TITLE, "Shopping Cart Page");
33 | shoppingCartPage.getQuantityOfProduct(1);
34 | TestLog.stepInfo("Quantity of Product At Index 1 is :: " + shoppingCartPage.getQuantityOfProduct(1));
35 | String updatedProductCount = "3";
36 | shoppingCartPage.updateQuantityOfProduct(1, updatedProductCount);
37 | shoppingCartPage.refreshProductQuantity(1);
38 | TestLog.stepInfo("Quantity of Product At Index 1 is :: " + shoppingCartPage.getQuantityOfProduct(1));
39 | Assert.assertEquals(shoppingCartPage.getQuantityOfProduct(1), Integer.parseInt(updatedProductCount), "Quantity of Product Mismatch");
40 | Assert.assertTrue(shoppingCartPage.modifyShoppingCartMessage(), "Cart Modification Failed");
41 |
42 |
43 | }
44 |
45 | @Test
46 | @Severity(BLOCKER)
47 | @Description("Calculate && Validate Product Price In Cart")
48 | public void validatePriceInTheCart() throws PageLoadException {
49 | HomePage homePage = goToHomePage();
50 | //Using Builder Pattern to Pass Product Details
51 | Product product = Product.builder().productName("MacBook").
52 | productId("1").
53 | productPrice(602.00).
54 | build();
55 | homePage.addToCartByIndex(Integer.parseInt(product.getProductId()));
56 | ShoppingCart shoppingCartPage = homePage.navigateToShoppingCartPage();
57 | assertPageTitle(shoppingCartPage.getTitle(driver), Constant.SHOPPING_CART_PAGE_TITLE, "Shopping Cart Page");
58 | shoppingCartPage.getQuantityOfProduct(1);
59 | TestLog.stepInfo("✅Quantity of Product At Index 1 is :: " + shoppingCartPage.getQuantityOfProduct(1));
60 | TestLog.stepInfo("✅Price Of the product At Index 1 is :: " + shoppingCartPage.getProductPrice(1));
61 | TestLog.stepInfo("✅Total price of Product " + shoppingCartPage.getTotalProductPrice(1));
62 | int quantityOfProduct = shoppingCartPage.getQuantityOfProduct(1);
63 | double productPrice = Double.parseDouble(CommonMethods.removeCurrencySymbols(shoppingCartPage.getTotalProductPrice(1)));
64 | Assert.assertEquals(productPrice * quantityOfProduct, Double.parseDouble(CommonMethods.removeCurrencySymbols(shoppingCartPage.getTotalProductPrice(1))));
65 | Assert.assertEquals(productPrice * quantityOfProduct, Double.parseDouble(CommonMethods.removeCurrencySymbols(shoppingCartPage.finalPriceOfCart())));
66 | TestLog.stepInfo("✅Final Cart Price is Successfully calculated and is " + shoppingCartPage.finalPriceOfCart());
67 |
68 | }
69 |
70 | @Test
71 | @Severity(BLOCKER)
72 | @Description("Calculate && Validate Product Price In Cart")
73 | public void modifyCartAndValidatePrices() throws PageLoadException {
74 | HomePage homePage = goToHomePage();
75 | //Using Builder Pattern to Pass Product Details
76 | Product product = Product.builder().productName("MacBook").
77 | productId("1").
78 | productPrice(602.00).
79 | build();
80 | homePage.addToCartByIndex(Integer.parseInt(product.getProductId()));
81 | ShoppingCart shoppingCartPage = homePage.navigateToShoppingCartPage();
82 | assertPageTitle(shoppingCartPage.getTitle(driver), Constant.SHOPPING_CART_PAGE_TITLE, "Shopping Cart Page");
83 | shoppingCartPage.getQuantityOfProduct(1);
84 | TestLog.stepInfo("✅Quantity of Product At Index 1 is :: " + shoppingCartPage.getQuantityOfProduct(1));
85 | TestLog.stepInfo("✅Price Of the product At Index 1 is :: " + shoppingCartPage.getProductPrice(1));
86 | TestLog.stepInfo("✅Total price of Product " + shoppingCartPage.getTotalProductPrice(1));
87 | int quantityOfProduct = shoppingCartPage.getQuantityOfProduct(1);
88 | double productPrice = Double.parseDouble(shoppingCartPage.getTotalProductPrice(1).replace("$", ""));
89 | double finalPrice = Double.parseDouble(CommonMethods.removeCurrencySymbols(shoppingCartPage.finalPriceOfCart()));
90 | Assert.assertEquals(productPrice * quantityOfProduct, finalPrice, "Product Price Mismatch");
91 | TestLog.stepInfo("✅Final Cart Price is Successfully calculated and is " + shoppingCartPage.finalPriceOfCart());
92 | String updatedProductCount = "3";
93 | shoppingCartPage.updateQuantityOfProduct(1, updatedProductCount);
94 | shoppingCartPage.refreshProductQuantity(1);
95 | shoppingCartPage.getQuantityOfProduct(1);
96 | TestLog.stepInfo("✅Quantity of Product At Index 1 is :: " + shoppingCartPage.getQuantityOfProduct(1));
97 | TestLog.stepInfo("✅Price Of the product At Index 1 is :: " + shoppingCartPage.getProductPrice(1));
98 | TestLog.stepInfo("✅Total price of Product " + shoppingCartPage.getTotalProductPrice(1));
99 | quantityOfProduct = shoppingCartPage.getQuantityOfProduct(1);
100 | productPrice = Double.parseDouble(CommonMethods.removeCurrencySymbols(shoppingCartPage.getProductPrice(1)));
101 | finalPrice = Double.parseDouble(CommonMethods.removeCurrencySymbols(shoppingCartPage.finalPriceOfCart()));
102 | Assert.assertEquals(productPrice * quantityOfProduct, finalPrice, "Product Price Mismatch");
103 | TestLog.stepInfo("✅Final Cart Price is Successfully calculated and is " + shoppingCartPage.finalPriceOfCart());
104 |
105 | }
106 |
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/cart/RemoveFromCartTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.cart;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.base.Product;
5 | import com.framework.exceptions.PageLoadException;
6 | import com.framework.factory.Constant;
7 | import com.framework.pages.HomePage;
8 | import com.framework.pages.ShoppingCart;
9 | import com.framework.reporting.TestLog;
10 | import io.qameta.allure.Description;
11 | import io.qameta.allure.Severity;
12 | import org.openqa.selenium.WebElement;
13 | import org.testng.Assert;
14 | import org.testng.annotations.Test;
15 | import java.util.Collections;
16 | import java.util.List;
17 | import java.util.stream.IntStream;
18 |
19 | import static io.qameta.allure.SeverityLevel.BLOCKER;
20 |
21 | public class RemoveFromCartTest extends BaseTest {
22 |
23 |
24 | @Test
25 | @Severity(BLOCKER)
26 | @Description("Add The Product By Index")
27 | public void removeProductFromCartByIndex() throws PageLoadException {
28 | HomePage homePage = goToHomePage();
29 | //Using Builder Pattern to Pass Product Details
30 | Product product = Product.builder().productName("MacBook").
31 | productId("1").
32 | productPrice(602.00).
33 | build();
34 | homePage.addToCartByIndex(Integer.parseInt(product.getProductId()));
35 |
36 | homePage.addToCartByIndex(2);
37 |
38 | ShoppingCart shoppingCartPage = homePage.navigateToShoppingCartPage();
39 |
40 | assertPageTitle(shoppingCartPage.getTitle(driver), Constant.SHOPPING_CART_PAGE_TITLE, "Shopping Cart Page");
41 |
42 |
43 | List reversedCart = shoppingCartPage.getShoppingCartItems();
44 | Collections.reverse(reversedCart);
45 |
46 | IntStream.range(0, reversedCart.size())
47 | .forEach(i -> {
48 | int index = reversedCart.size() - i;
49 |
50 | TestLog.stepInfo("Product Name is :: " + shoppingCartPage.getProductName(index));
51 | TestLog.stepInfo("Product Model is :: " + shoppingCartPage.getProductModel(index));
52 | TestLog.stepInfo("Product Price is :: " + shoppingCartPage.getProductPrice(index));
53 | TestLog.stepInfo("Total Product Price is :: " + shoppingCartPage.getTotalProductPrice(index));
54 | TestLog.stepInfo("Quantity of Product is :: " + shoppingCartPage.getQuantityOfProduct(index));
55 |
56 | shoppingCartPage.removeFromCartByIndex(index);
57 | });
58 |
59 | Assert.assertTrue(shoppingCartPage.emptyShoppingCartMessage(), "Shopping Cart Empty Msg Not Displayed");
60 |
61 |
62 | }
63 |
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/login/LoginTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.login;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.exceptions.PageLoadException;
5 | import com.framework.factory.Constant;
6 | import com.framework.pages.Account;
7 | import com.framework.pages.HomePage;
8 | import com.framework.pages.Login;
9 | import com.framework.reporting.TestLog;
10 | import io.qameta.allure.Description;
11 | import io.qameta.allure.Severity;
12 | import org.testng.Assert;
13 | import org.testng.annotations.Test;
14 | import static io.qameta.allure.SeverityLevel.BLOCKER;
15 |
16 | public class LoginTest extends BaseTest {
17 |
18 | private Login loginPage;
19 | private Account accountPage;
20 |
21 | @Test(groups = {"smoke"})
22 | @Severity(BLOCKER)
23 | @Description("Verify UI Page is Running")
24 | public void openHomePage() throws PageLoadException {
25 | HomePage homePage = launchHomePage();
26 | assertPageTitle(homePage.getTitle(driver), Constant.HOME_PAGE_TITLE, "Home Page");
27 | TestLog.testPass("Verify UI Page is Running Test Case Passed");
28 | }
29 |
30 | @Test(groups = {"smoke"})
31 | @Severity(BLOCKER)
32 | @Description("Verify User Is Able to Login")
33 | public void verifyLoginUser() throws PageLoadException {
34 | HomePage homePage = launchHomePage();
35 | loginPage = homePage.navigateToLoginPage();
36 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
37 |
38 | accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
39 | TestLog.stepInfo("Title of the Account Page is: " + accountPage.getTitle(driver));
40 |
41 | TestLog.testPass("✅ Verify Login User Test Case Passed");
42 | }
43 |
44 | @Test(groups = {"smoke"})
45 | @Severity(BLOCKER)
46 | @Description("Invalid User should not be able to login")
47 | public void verifyInvalidLoginUser() throws PageLoadException {
48 | HomePage homePage = launchHomePage();
49 | loginPage = homePage.navigateToLoginPage();
50 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
51 |
52 | accountPage = loginPage.loginAsExistingUser("test123", "test123");
53 | Assert.assertEquals(loginPage.invalidUser(), Constant.INVALID_USER_WARNING, "Invalid user warning not shown");
54 |
55 | TestLog.stepInfo("Invalid login verified, warning displayed as expected.");
56 | TestLog.testPass("✅ Verify Invalid Login Test Case Passed");
57 | }
58 |
59 | @Test
60 | @Severity(BLOCKER)
61 | @Description("Validate Home Page Objects")
62 | public void verifyHomePageElementsArePresent() throws PageLoadException {
63 | HomePage homePage = launchHomePage();
64 | assertPageTitle(homePage.getTitle(driver), Constant.HOME_PAGE_TITLE, "Home Page");
65 | verifyElement(homePage.isSearchIconEnabled(), "Search Icon");
66 | verifyElement(homePage.isPageLogoDisplayed(), "Page Logo");
67 | verifyElement(homePage.isSearchBarEnabled(), "Search Bar");
68 | verifyElement(homePage.isWishListEnabled(), "Wish List");
69 | verifyElement(homePage.isMyAccountEnabled(), "My Account List");
70 | TestLog.testPass("✅ Home Page UI element validation passed.");
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/login/LogoutTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.login;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.exceptions.PageLoadException;
5 | import com.framework.factory.Constant;
6 | import com.framework.pages.Account;
7 | import com.framework.pages.HomePage;
8 | import com.framework.pages.Login;
9 | import com.framework.reporting.TestLog;
10 | import io.qameta.allure.Description;
11 | import io.qameta.allure.Severity;
12 | import io.qameta.allure.SeverityLevel;
13 | import org.testng.annotations.Test;
14 |
15 | public class LogoutTest extends BaseTest {
16 |
17 | private Login loginPage;
18 | private Account accountPage;
19 | @Test(groups = {"smoke"})
20 | @Description("User Logs Out Successfully")
21 | @Severity(SeverityLevel.BLOCKER)
22 | private void existingUserLogOut() throws PageLoadException {
23 | HomePage homePage = launchHomePage();
24 | loginPage = homePage.navigateToLoginPage();
25 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
26 | accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
27 | TestLog.stepInfo("Title of the Account Page is: " + accountPage.getTitle(driver));
28 | TestLog.stepInfo("✅ User is Successfully Logged In");
29 | Account.Logout logoutPage=accountPage.logout();
30 | verifyLogoutPageElements(logoutPage);
31 | TestLog.stepInfo("✅ User is Successfully Logged Out");
32 |
33 | }
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/search/AddToCart.java:
--------------------------------------------------------------------------------
1 | package com.tests.search;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.exceptions.PageLoadException;
5 | import com.framework.factory.Constant;
6 | import com.framework.pages.*;
7 | import com.framework.reporting.TestLog;
8 | import io.qameta.allure.Description;
9 | import io.qameta.allure.Severity;
10 | import org.openqa.selenium.devtools.v85.backgroundservice.BackgroundService;
11 | import org.testng.Assert;
12 | import org.testng.annotations.Test;
13 |
14 | import static io.qameta.allure.SeverityLevel.BLOCKER;
15 |
16 | public class AddToCart extends BaseTest {
17 |
18 | @Test
19 | @Severity(BLOCKER)
20 | @Description("Search Product And Add To Cart")
21 | private void addToWishListFromSearchPage() throws PageLoadException {
22 |
23 | HomePage homePage = launchHomePage();
24 | Login loginPage = homePage.navigateToLoginPage();
25 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
26 |
27 | Account accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
28 | homePage = accountPage.navigateToHomePage();
29 |
30 | Search searchPage = homePage.searchProduct("Macbook");
31 |
32 | Assert.assertEquals(searchPage.getNoOfProduct().size(), 3, "Product Size Mismatch");
33 |
34 | searchPage.addToCart(1);
35 |
36 | ShoppingCart shoppingCartPage=searchPage.navigateToCartPage();
37 | shoppingCartPage.getQuantityOfProduct(1);
38 | TestLog.stepInfo("Quantity of Product At Index 1 is :: " + shoppingCartPage.getQuantityOfProduct(1));
39 |
40 |
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/search/AddToWishListTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.search;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.exceptions.PageLoadException;
5 | import com.framework.factory.Constant;
6 | import com.framework.pages.Account;
7 | import com.framework.pages.HomePage;
8 | import com.framework.pages.Login;
9 | import com.framework.pages.Search;
10 | import com.framework.reporting.TestLog;
11 | import io.qameta.allure.Description;
12 | import io.qameta.allure.Severity;
13 | import org.testng.Assert;
14 | import org.testng.annotations.Test;
15 |
16 | import static io.qameta.allure.SeverityLevel.BLOCKER;
17 |
18 | public class AddToWishListTest extends BaseTest {
19 |
20 |
21 |
22 | @Test
23 | @Severity(BLOCKER)
24 | @Description("Search Product And Add To WishList")
25 | private void addToWishListFromSearchPage() throws PageLoadException {
26 |
27 | HomePage homePage = launchHomePage();
28 | Login loginPage = homePage.navigateToLoginPage();
29 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
30 |
31 | Account accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
32 | homePage = accountPage.navigateToHomePage();
33 |
34 | Search searchPage = homePage.searchProduct("Macbook");
35 |
36 | Assert.assertEquals(searchPage.getNoOfProduct().size(), 3, "Product Size Mismatch");
37 |
38 | searchPage.addToWishList(1);
39 |
40 | Account.WishList wishListPage=searchPage.navigateToWishListPage();
41 | assertPageTitle(wishListPage.getTitle(driver), Constant.WISHLIST_PAGE_TITLE, "Wishlist Page");
42 | TestLog.stepInfo("User is navigated to Wishlist Page");
43 | TestLog.stepInfo("No of Products in WishList is " + wishListPage.getWishList().size());
44 | Assert.assertEquals(wishListPage.getWishList().size(),1);
45 |
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/search/FilterSearchTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.search;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.base.CommonMethods;
5 | import com.framework.exceptions.PageLoadException;
6 | import com.framework.factory.Constant;
7 | import com.framework.pages.Account;
8 | import com.framework.pages.HomePage;
9 | import com.framework.pages.Login;
10 | import com.framework.pages.Search;
11 | import com.framework.reporting.TestLog;
12 | import io.qameta.allure.Description;
13 | import io.qameta.allure.Severity;
14 | import org.testng.Assert;
15 | import org.testng.annotations.Test;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | import static io.qameta.allure.SeverityLevel.BLOCKER;
21 |
22 | public class FilterSearchTest extends BaseTest {
23 |
24 |
25 | @Test
26 | @Severity(BLOCKER)
27 | @Description("Search Product And Sort By Price In Ascending Order")
28 | private void searchProductInAscendingOrder() throws PageLoadException {
29 |
30 | HomePage homePage = launchHomePage();
31 | Login loginPage = homePage.navigateToLoginPage();
32 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
33 |
34 | Account accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
35 | homePage = accountPage.navigateToHomePage();
36 |
37 | Search searchPage = homePage.searchProduct("Macbook");
38 | searchPage.sortProductByPriceLowToHigh();
39 |
40 | Assert.assertEquals(searchPage.getNoOfProduct().size(), 3, "Product Size Mismatch");
41 |
42 | List listOfSearchedProducts = new java.util.ArrayList<>(List.of());
43 |
44 | for (int i = 1; i <= searchPage.getNoOfProduct().size(); i++) {
45 |
46 | String price = priceExtractor(searchPage.getProductPrice(i), "\\$\\d{1,3}(,\\d{3})*\\.\\d{2}");
47 | double finalPrice = Double.parseDouble(CommonMethods.removeCurrencySymbols(price));
48 | listOfSearchedProducts.add(finalPrice);
49 | }
50 | Assert.assertTrue(CommonMethods.isSorted(listOfSearchedProducts, true), "Price Of Products is not in ascending order");
51 | TestLog.stepInfo("Product List Is Sorted in Ascending Order Based on Price.");
52 |
53 | }
54 |
55 | @Test
56 | @Severity(BLOCKER)
57 | @Description("Search Product And Sort By Price In Descending Order")
58 | private void searchProductInDescendingOrder() throws PageLoadException {
59 |
60 | HomePage homePage = launchHomePage();
61 | Login loginPage = homePage.navigateToLoginPage();
62 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
63 |
64 | Account accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
65 | homePage = accountPage.navigateToHomePage();
66 |
67 | Search searchPage = homePage.searchProduct("Macbook");
68 | searchPage.getListView();
69 | searchPage.sortProductByPriceHighToLow();
70 |
71 | Assert.assertEquals(searchPage.getNoOfProduct().size(), 3, "Product Size Mismatch");
72 |
73 | List listOfSearchedProducts = new ArrayList<>(List.of());
74 |
75 | for (int i = 1; i <= searchPage.getNoOfProduct().size(); i++) {
76 |
77 | String price = priceExtractor(searchPage.getProductPrice(i), "\\$\\d{1,3}(,\\d{3})*\\.\\d{2}");
78 | double finalPrice = Double.parseDouble(CommonMethods.removeCurrencySymbols(price));
79 | listOfSearchedProducts.add(finalPrice);
80 | }
81 | Assert.assertTrue(CommonMethods.isSorted(listOfSearchedProducts, false), "Price Of Products is not in descending order");
82 | TestLog.stepInfo("Product List Is Sorted in Descending Order Based on Price.");
83 |
84 |
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/search/SearchTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.search;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.exceptions.PageLoadException;
5 | import com.framework.factory.Constant;
6 | import com.framework.pages.Account;
7 | import com.framework.pages.HomePage;
8 | import com.framework.pages.Login;
9 | import com.framework.pages.Search;
10 | import com.framework.reporting.TestLog;
11 | import io.qameta.allure.Description;
12 | import io.qameta.allure.Severity;
13 | import org.testng.Assert;
14 | import org.testng.annotations.Test;
15 |
16 | import static io.qameta.allure.SeverityLevel.BLOCKER;
17 |
18 | public class SearchTest extends BaseTest {
19 |
20 |
21 | @Test
22 | @Severity(BLOCKER)
23 | @Description("Search Product")
24 | private void searchProduct() throws PageLoadException {
25 |
26 | HomePage homePage = launchHomePage();
27 | Login loginPage = homePage.navigateToLoginPage();
28 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
29 |
30 | Account accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
31 | homePage = accountPage.navigateToHomePage();
32 |
33 | Search searchPage = homePage.searchProduct("Macbook");
34 |
35 | Assert.assertEquals(searchPage.getNoOfProduct().size(),1,"Product Size Mismatch");
36 |
37 | TestLog.stepInfo("Total No Of Products In Search Appearances is :::" + searchPage.getNoOfProduct().size());
38 |
39 | }
40 |
41 | @Test
42 | @Severity(BLOCKER)
43 | @Description("Search Unavailable Product")
44 | private void searchUnavailableProduct() throws PageLoadException {
45 |
46 | HomePage homePage = launchHomePage();
47 | Login loginPage = homePage.navigateToLoginPage();
48 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
49 |
50 | Account accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
51 | homePage = accountPage.navigateToHomePage();
52 |
53 | Search searchPage = homePage.searchProduct("Suzuki");
54 |
55 | Assert.assertTrue(searchPage.isNoProductFound());
56 |
57 | Assert.assertEquals(searchPage.getNoOfProduct().size(),0,"Product Size Mismatch");
58 |
59 | TestLog.stepInfo("Total No Of Products In Search Appearances is :::" + searchPage.getNoOfProduct().size());
60 |
61 | }
62 |
63 | @Test
64 | @Severity(BLOCKER)
65 | @Description("Search Product in List View ")
66 | private void searchProductInListView() throws PageLoadException {
67 |
68 | HomePage homePage = launchHomePage();
69 | Login loginPage = homePage.navigateToLoginPage();
70 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
71 |
72 | Account accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
73 | homePage = accountPage.navigateToHomePage();
74 |
75 | Search searchPage = homePage.searchProduct("Macbook");
76 |
77 | searchPage.getListView();
78 |
79 | Assert.assertEquals(searchPage.getNoOfProduct().size(),3,"Product Size Mismatch");
80 |
81 | TestLog.stepInfo("Total No Of Products In Search Appearances is :::" + searchPage.getNoOfProduct().size());
82 |
83 | }
84 |
85 | @Test
86 | @Severity(BLOCKER)
87 | @Description("Search Product in Grid View ")
88 | private void searchProductInGridView() throws PageLoadException {
89 |
90 | HomePage homePage = launchHomePage();
91 | Login loginPage = homePage.navigateToLoginPage();
92 | assertPageTitle(loginPage.getTitle(driver), Constant.LOGIN_PAGE_TITLE, "Login Page");
93 |
94 | Account accountPage = loginPage.loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD);
95 | homePage = accountPage.navigateToHomePage();
96 |
97 | Search searchPage = homePage.searchProduct("Macbook");
98 |
99 | searchPage.getGridView();
100 |
101 | Assert.assertEquals(searchPage.getNoOfProduct().size(),3,"Product Size Mismatch");
102 |
103 | TestLog.stepInfo("Total No Of Products In Search Appearances is :::" + searchPage.getNoOfProduct().size());
104 |
105 | }
106 |
107 |
108 |
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/wishlist/AddToWishListTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.wishlist;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.base.Product;
5 | import com.framework.exceptions.PageLoadException;
6 | import com.framework.factory.Constant;
7 | import com.framework.listener.CustomListener;
8 | import com.framework.pages.Account;
9 | import com.framework.pages.HomePage;
10 | import com.framework.reporting.TestLog;
11 | import io.qameta.allure.Description;
12 | import io.qameta.allure.Severity;
13 | import org.testng.Assert;
14 | import org.testng.annotations.Listeners;
15 | import org.testng.annotations.Test;
16 |
17 | import static io.qameta.allure.SeverityLevel.BLOCKER;
18 |
19 | @Listeners(CustomListener.class)
20 | public class AddToWishListTest extends BaseTest {
21 | @Test()
22 | @Severity(BLOCKER)
23 | @Description("Add The Product To WishList By Index")
24 | public void addProductToWishListByIndex() throws PageLoadException {
25 | HomePage homePage = goToHomePage();
26 | //Using Builder Pattern to Pass Product Details
27 | Product product = Product.builder().productName("MacBook").
28 | productId("1").
29 | productPrice(602.00).
30 | build();
31 | homePage.addToWishListByIndex(Integer.parseInt(product.getProductId()));
32 | String wishListItemDetails = homePage.returnWishListItem();
33 | int noOfProductsInWishList = Integer.parseInt(wishListItemDetails.substring(wishListItemDetails.indexOf('(') + 1, wishListItemDetails.indexOf(')')));
34 | Assert.assertEquals(noOfProductsInWishList, 1, "Number of products in Cart is wrong");
35 | TestLog.stepInfo("No of Products in WishList is " + noOfProductsInWishList);
36 |
37 |
38 |
39 | }
40 |
41 | @Test
42 | @Severity(BLOCKER)
43 | @Description("Add The Product To WishList By Name")
44 | public void addProductToWishListByName() throws PageLoadException {
45 | HomePage homePage = goToHomePage();
46 | //Using Builder Pattern to Pass Product Details
47 | Product product = Product.builder().productName("iPhone").
48 | productId("2").
49 | productPrice(602.00).
50 | build();
51 | homePage.addToWishListByProductName(product.getProductName());
52 | String wishListItemDetails = homePage.returnWishListItem();
53 | int noOfProductsInWishList = Integer.parseInt(wishListItemDetails.substring(wishListItemDetails.indexOf('(') + 1, wishListItemDetails.indexOf(')')));
54 | Assert.assertEquals(noOfProductsInWishList, 1, "Number of products in Cart is wrong");
55 | TestLog.stepInfo("No of Products in the WishList is " + noOfProductsInWishList);
56 |
57 | }
58 |
59 | @Test
60 | @Severity(BLOCKER)
61 | @Description("Add The Multiple Products To WishList ")
62 | public void addMultipleProductToWishList() throws PageLoadException {
63 | HomePage homePage = goToHomePage();
64 | //Using Builder Pattern to Pass Product Details
65 | Product product = Product.builder().productName("iPhone").
66 | productId("2").
67 | productPrice(602.00).
68 | build();
69 | homePage.addToWishListByProductName(product.getProductName());
70 | homePage.addToWishListByIndex(1);
71 | String wishListItemDetails = homePage.returnWishListItem();
72 | int noOfProductsInWishList = Integer.parseInt(wishListItemDetails.substring(wishListItemDetails.indexOf('(') + 1, wishListItemDetails.indexOf(')')));
73 | Assert.assertEquals(noOfProductsInWishList, 2, "Number of products in Cart is wrong");
74 | TestLog.stepInfo("No of Products in the WishList is " + noOfProductsInWishList);
75 |
76 | }
77 |
78 | @Test
79 | @Severity(BLOCKER)
80 | @Description("Add Same Product To WishList Multiple Times")
81 | public void addProductMultipleTimes() throws PageLoadException {
82 | HomePage homePage = launchHomePage();
83 | homePage = homePage.navigateToLoginPage().loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD).navigateToHomePage();
84 | //Using Builder Pattern to Pass Product Details
85 | Product product = Product.builder().productName("iPhone").
86 | productId("2").
87 | productPrice(602.00).
88 | build();
89 | homePage.addToWishListByProductName(product.getProductName());
90 | homePage.addToWishListByProductName(product.getProductName());
91 | Account.WishList wishListPage=homePage.navigateToWishListPage();
92 | Assert.assertEquals(wishListPage.getWishList().size(), 1, "Number of Products in WishList is Wrong");
93 | TestLog.stepInfo("Total No of Products in WishList is " + wishListPage.getWishList().size());
94 | Account.WishList wishlistPage = homePage.navigateToWishListPage();
95 | assertPageTitle(wishlistPage.getTitle(driver), Constant.WISHLIST_PAGE_TITLE, "Wishlist Page");
96 | TestLog.stepInfo("User is navigated to Wishlist Page");
97 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
98 | Assert.assertEquals(wishlistPage.getWishList().size(),1, "Number of Products in WishList is Wrong");
99 | }
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/wishlist/ModifyWishListTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.wishlist;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.exceptions.PageLoadException;
5 | import com.framework.factory.Constant;
6 | import com.framework.pages.Account;
7 | import com.framework.pages.HomePage;
8 | import com.framework.pages.ShoppingCart;
9 | import com.framework.reporting.TestLog;
10 | import io.qameta.allure.Description;
11 | import io.qameta.allure.Severity;
12 | import org.testng.Assert;
13 | import org.testng.annotations.Test;
14 |
15 | import static io.qameta.allure.SeverityLevel.BLOCKER;
16 |
17 | public class ModifyWishListTest extends BaseTest {
18 |
19 |
20 | @Test
21 | @Severity(BLOCKER)
22 | @Description("Move Product from WishList To Shopping Cart")
23 | public void moveProductFromWishlistToCart() throws PageLoadException {
24 |
25 | HomePage homePage = launchHomePage();
26 | homePage = homePage.navigateToLoginPage().loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD).navigateToHomePage();
27 | homePage.addToWishListByIndex(1);
28 | Account.WishList wishlistPage = homePage.navigateToWishListPage();
29 | assertPageTitle(wishlistPage.getTitle(driver), Constant.WISHLIST_PAGE_TITLE, "Wishlist Page");
30 | TestLog.stepInfo("User is navigated to Wishlist Page");
31 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
32 | wishlistPage.addToShoppingCart(1);
33 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
34 | ShoppingCart shoppingCartBtn= wishlistPage.navigateToCartPage();
35 | assertPageTitle(driver.getTitle(), Constant.SHOPPING_CART_PAGE_TITLE, "Shopping Cart");
36 | Assert.assertEquals(shoppingCartBtn.getShoppingCartItems().size(), 1);
37 | TestLog.stepInfo("Size of the shopping cart is " + shoppingCartBtn.getShoppingCartItems().size());
38 |
39 | }
40 |
41 | @Test
42 | @Severity(BLOCKER)
43 | @Description("Move Product from WishList To Shopping Cart")
44 | public void moveMultipleProductFromWishlistToCart() throws PageLoadException {
45 |
46 | HomePage homePage = launchHomePage();
47 | homePage = homePage.navigateToLoginPage().loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD).navigateToHomePage();
48 | homePage.addToWishListByIndex(1);
49 | homePage.addToWishListByIndex(2);
50 | Account.WishList wishlistPage = homePage.navigateToWishListPage();
51 | assertPageTitle(wishlistPage.getTitle(driver), Constant.WISHLIST_PAGE_TITLE, "Wishlist Page");
52 | TestLog.stepInfo("User is navigated to Wishlist Page");
53 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
54 | wishlistPage.addToShoppingCart(2);
55 | wishlistPage.addToShoppingCart(1);
56 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
57 | ShoppingCart shoppingCartBtn= wishlistPage.navigateToCartPage();
58 | assertPageTitle(driver.getTitle(), Constant.SHOPPING_CART_PAGE_TITLE, "Shopping Cart");
59 | Assert.assertEquals(shoppingCartBtn.getShoppingCartItems().size(), 2);
60 | TestLog.stepInfo("Size of the shopping cart is " + shoppingCartBtn.getShoppingCartItems().size());
61 |
62 | }
63 |
64 |
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/test/java/com/tests/wishlist/RemoveFromWishListTest.java:
--------------------------------------------------------------------------------
1 | package com.tests.wishlist;
2 |
3 | import com.base.BaseTest;
4 | import com.framework.base.Product;
5 | import com.framework.exceptions.PageLoadException;
6 | import com.framework.factory.Constant;
7 | import com.framework.pages.Account;
8 | import com.framework.pages.HomePage;
9 | import com.framework.reporting.TestLog;
10 | import io.qameta.allure.Description;
11 | import io.qameta.allure.Severity;
12 | import org.testng.Assert;
13 | import org.testng.annotations.Test;
14 |
15 | import static io.qameta.allure.SeverityLevel.BLOCKER;
16 |
17 | public class RemoveFromWishListTest extends BaseTest {
18 |
19 |
20 | @Test
21 | @Severity(BLOCKER)
22 | @Description("Remove From WishList By Index")
23 | public void removeProductFromWishListByIndex() throws PageLoadException {
24 |
25 | HomePage homePage = launchHomePage();
26 | homePage = homePage.navigateToLoginPage().loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD).navigateToHomePage();
27 | Product product = Product.builder().productName("MacBook").
28 | productId("1").
29 | productPrice(602.00).
30 | build();
31 | homePage.addToWishListByIndex(Integer.parseInt(product.getProductId()));
32 | String wishListItemDetails = homePage.returnWishListItem();
33 | int noOfProductsInWishList = Integer.parseInt(wishListItemDetails.substring(wishListItemDetails.indexOf('(') + 1, wishListItemDetails.indexOf(')')));
34 | Assert.assertEquals(noOfProductsInWishList, 1, "Number of products in Cart is wrong");
35 | TestLog.stepInfo("No of Products in WishList is " + noOfProductsInWishList);
36 |
37 | Account.WishList wishlistPage = homePage.navigateToWishListPage();
38 | assertPageTitle(wishlistPage.getTitle(driver), Constant.WISHLIST_PAGE_TITLE, "Wishlist Page");
39 | TestLog.stepInfo("User is navigated to Wishlist Page");
40 | String productName = wishlistPage.getProductName(1);
41 | TestLog.stepInfo("Product Name is " + productName);
42 | TestLog.stepInfo("Product Model is " + wishlistPage.getProductModel(1));
43 | TestLog.stepInfo("Product Unit Price is " + wishlistPage.getProductUnitPrice(1));
44 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
45 | TestLog.stepInfo("Product is Available " + wishlistPage.isAvailable(1));
46 | wishlistPage.removeFromWishList(1);
47 | Assert.assertTrue(wishlistPage.verifyEmptyWishList(), "Wishlist is not empty");
48 | TestLog.stepInfo("Wish list is empty.....");
49 |
50 | }
51 |
52 | @Test
53 | @Severity(BLOCKER)
54 | @Description("Add Multiple Products and Remove Single Product From WishList By Index")
55 | public void removeSingleProductFromWishListByIndex() throws PageLoadException {
56 |
57 | HomePage homePage = launchHomePage();
58 | homePage = homePage.navigateToLoginPage().loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD).navigateToHomePage();
59 | homePage.addToWishListByIndex(1);
60 | homePage.addToWishListByIndex(2);
61 | Account.WishList wishlistPage = homePage.navigateToWishListPage();
62 | assertPageTitle(wishlistPage.getTitle(driver), Constant.WISHLIST_PAGE_TITLE, "Wishlist Page");
63 | TestLog.stepInfo("User is navigated to Wishlist Page");
64 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
65 | wishlistPage.removeFromWishList(1);
66 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
67 | TestLog.stepInfo("Wish list is not empty.....");
68 |
69 | }
70 | @Test
71 | @Severity(BLOCKER)
72 | @Description("Remove All Product From WishList By Index")
73 | public void removeAllProductsFromWishListByIndex() throws PageLoadException {
74 |
75 | HomePage homePage = launchHomePage();
76 | homePage = homePage.navigateToLoginPage().loginAsExistingUser(Constant.EMAIL_ADDRESS, Constant.PWD).navigateToHomePage();
77 | homePage.addToWishListByIndex(1);
78 | homePage.addToWishListByIndex(2);
79 | Account.WishList wishlistPage = homePage.navigateToWishListPage();
80 | assertPageTitle(wishlistPage.getTitle(driver), Constant.WISHLIST_PAGE_TITLE, "Wishlist Page");
81 | TestLog.stepInfo("User is navigated to Wishlist Page");
82 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
83 | TestLog.stepInfo("Product At Index 1 is Available" + wishlistPage.isAvailable(1));
84 | wishlistPage.removeFromWishList(1);
85 | TestLog.stepInfo("No of Products in WishList is " + wishlistPage.getWishList().size());
86 | wishlistPage.removeFromWishList(1);
87 | Assert.assertTrue(wishlistPage.verifyEmptyWishList(), "Wishlist is not empty");
88 | TestLog.stepInfo("Wish list is empty.....");
89 |
90 |
91 | }
92 |
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/src/test/resources/screenshots/addProductToWishListByIndex_1746775387469.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codewithmnglm/UIAutomation/84ec30ae8ed2181ea4f31c6b2294860fd0bc359f/src/test/resources/screenshots/addProductToWishListByIndex_1746775387469.png
--------------------------------------------------------------------------------
/src/test/resources/screenshots/registerUser_1747220308640.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codewithmnglm/UIAutomation/84ec30ae8ed2181ea4f31c6b2294860fd0bc359f/src/test/resources/screenshots/registerUser_1747220308640.png
--------------------------------------------------------------------------------
/src/test/resources/screenshots/registerUser_1747220404214.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codewithmnglm/UIAutomation/84ec30ae8ed2181ea4f31c6b2294860fd0bc359f/src/test/resources/screenshots/registerUser_1747220404214.png
--------------------------------------------------------------------------------
/testng-regression.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/testng-smoke.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/testng.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------