├── .gitignore ├── .idea ├── .gitignore ├── misc.xml └── vcs.xml ├── README.md ├── pom.xml └── src └── test ├── java ├── RunCucumberTest.java ├── core │ ├── drivers │ │ ├── DriverManager.java │ │ └── DriverProvider.java │ └── library │ │ ├── Constants.java │ │ └── PropertyLoader.java ├── hooks │ └── Hooks.java ├── pages │ ├── browseragnosticfeatures │ │ ├── DialogBoxPage.java │ │ └── InfiniteScrollingPage.java │ ├── common │ │ └── BasePage.java │ ├── pageobjectmodel │ │ └── LoginFormPage.java │ └── webDriverFundamentals │ │ ├── DragAndDropPage.java │ │ ├── DropDownMenuPage.java │ │ ├── HomePage.java │ │ ├── NavigationPage.java │ │ └── webform_components │ │ ├── WebFormComponentsPage.java │ │ └── WebFormTextElement.java └── steps │ ├── browseragnosticfeatures │ ├── DialogBoxStepDefinitions.java │ └── InfiniteScrollingStepDefinitions.java │ ├── pageobjectmodel │ └── LoginFormStepDefinitions.java │ └── webdriverfundamentals │ ├── DragAndDropStepDefinitions.java │ ├── DropDownMenuStepDefinitions.java │ ├── HomeStepDefinitions.java │ ├── NavigationStepDefinitions.java │ └── WebFormComponentsStepDefinitions.java └── resources ├── cucumber.properties ├── features ├── browser_agnostic_features │ ├── dialogBox.feature │ └── infiniteScrolling.feature ├── page_object _model │ └── loginForm.feature └── webdriver_fundamental │ ├── dragAndDrop.feature │ ├── dropdown_menu.feature │ ├── home.feature │ ├── navigation_page.feature │ └── webFormComponents.feature └── files ├── Demo.png ├── report.png └── test.jpg /.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/misc.xml 11 | .idea/libraries/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | 16 | ### Eclipse ### 17 | .apt_generated 18 | .classpath 19 | .factorypath 20 | .project 21 | .settings 22 | .springBeans 23 | .sts4-cache 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | build/ 32 | !**/src/main/**/build/ 33 | !**/src/test/**/build/ 34 | 35 | ### VS Code ### 36 | .vscode/ 37 | 38 | ### Mac OS ### 39 | .DS_Store -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | /encodings.xml 5 | /dbnavigator.xml 6 | /uiDesigner.xml 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Selenium WebDriver Java Testing Example 2 | 3 | This repository provides an example of using **Selenium WebDriver** with **Java**, **JUnit**, **Cucumber**, and **Gherkin** for browser automation and UI testing. It includes a simple framework for managing WebDriver instances, reusable UI methods, page objects, and example tests that interact with a web form on [Boni García's Selenium WebDriver page](https://bonigarcia.dev/selenium-webdriver-java/web-form.html). 4 | 5 | The tests are written using the **Cucumber** framework in **Gherkin** syntax, which allows for behavior-driven development (BDD) style scenarios. **JUnit** is used as the test runner to execute the feature files. 6 | 7 | 8 | ## Overview 9 | 10 | This project demonstrates how to build a basic Selenium WebDriver testing framework in Java. The repository contains: 11 | 12 | - **Driver management** with thread-safe WebDriver instances. 13 | - **Reusable UI methods** and **page objects** for interacting with web elements. 14 | - **Sample test scenarios** that cover various web components (text input, password fields, checkboxes, dropdowns, etc.). 15 | - **Cucumber-based feature files** for defining test scenarios in a behavior-driven development (BDD) style. 16 | 17 | ## Cucumber-Based Feature Files 18 | 19 | This repository includes comprehensive Cucumber feature files written in Gherkin syntax. These files define test scenarios for behavior-driven development (BDD) and cover a wide range of functionalities: 20 | 21 | - **Infinite Scroll**: 22 | - Validates dynamic content loading as the user scrolls to the bottom of the page. 23 | - Ensures new content is appended without triggering a full-page reload. 24 | 25 | - **Drag and Drop**: 26 | - Tests drag-and-drop functionality, verifying that elements are repositioned correctly. 27 | 28 | - **Dropdown Menu Interaction**: 29 | - Scenarios for interacting with dropdown buttons and verifying menu item visibility and selection. 30 | 31 | - **Home Page Navigation**: 32 | - Tests navigation to various pages using specific buttons on the home page. 33 | 34 | - **Web Form Components**: 35 | - Covers interaction with various form elements, including: 36 | - Text inputs and password fields. 37 | - Dropdown menus (select and data list). 38 | - File uploads. 39 | - Checkboxes and radio buttons. 40 | - Date picker, color picker, and range slider components. 41 | 42 | - **Navigation Page**: 43 | - Validates button interactions and dynamic content updates. 44 | 45 | - **Login Functionality**: 46 | - Validates user authentication by testing login attempts with valid and invalid credentials. 47 | - Ensures appropriate success or error messages are displayed based on login attempts. 48 | 49 | - **Button Functionalities**: 50 | - Verifies interactions with alert, confirm, and prompt dialogs. 51 | - Ensures correct messages are displayed when accepting, canceling, or inputting text in prompt dialogs. 52 | - Tests modal dialogs for expected behavior when closed or when changes are saved. 53 | 54 | 55 | ## Class Structure: 56 | 57 | ### `core.drivers` 58 | 59 | - **`DriverManager`** 60 | - Manages web driver instances for multiple threads. 61 | - Likely includes methods for creating, getting, and removing WebDriver instances in a thread-safe manner. 62 | 63 | - **`DriverProvider`** 64 | - Provides the necessary WebDriver instances (like Chrome or Firefox). 65 | - Handles configurations like ChromeOptions for setting up the driver (i.e., headless mode, browser-specific properties, etc.). 66 | - Likely manages different browsers and timeout configurations. 67 | 68 | --- 69 | 70 | ### `core.library` 71 | 72 | - **`Constants`** 73 | - Contains static final variables used throughout the test, such as timeouts, URL constants, browser names, etc. 74 | 75 | - **`PropertyLoader`** 76 | - A Singleton class designed to load configuration properties (i.e., from `.properties` files) and ensure that only one instance of the class is used throughout the tests. 77 | - Ensures centralized and controlled access to configuration values. 78 | 79 | --- 80 | 81 | ### `pages.browseragnosticfeatures` 82 | 83 | - **`DialogBoxPage`** 84 | - A Page Object that deals with browser-agnostic features like dialog boxes. 85 | - Contains logic for interacting with alerts and dialog elements (using `Alert` and `WebDriverWait`). 86 | 87 | - **`InfiniteScrollingPage`** 88 | - A Page Object handling infinite scroll features in the web application. 89 | - Contains interactions and waits that are unique to infinite scrolling scenarios. 90 | 91 | --- 92 | 93 | ### `pages.common` 94 | 95 | - **`BasePage`** 96 | - The base class for all pages that could have common elements or actions that every page shares. 97 | - Most likely, this class contains a constructor for page factory initialization (with `PageFactory.initElements(driver, this)`). 98 | - Also includes driver and WebDriver-specific methods. 99 | 100 | --- 101 | 102 | ### `pages.pageobjectmodel` 103 | 104 | - **`LoginFormPage`** 105 | - A Page Object model for login form interactions (like entering credentials, clicking login buttons, etc.). 106 | - Contains specific methods for interacting with the login form. 107 | 108 | --- 109 | 110 | ### `pages.webDriverFundamentals.webform_components` 111 | 112 | - **`WebFormComponentsPage`** 113 | - A Page Object for handling form components such as text fields, checkboxes, dropdowns, etc. 114 | - Includes elements like `WebFormTextElement` to distinguish different types of form inputs. 115 | 116 | - **`WebFormTextElement` (Enum)** 117 | - An enumeration that identifies different types of text-based form fields like `PASSWORD`, `TEXT`, and `TEXT_AREA`. 118 | 119 | --- 120 | 121 | ### `pages.webDriverFundamentals` 122 | 123 | - **`DragAndDropPage`** 124 | - A Page Object dedicated to drag-and-drop interactions. 125 | - Contains logic to simulate drag-and-drop events using WebDriver. 126 | 127 | - **`DropDownMenuPage`** 128 | - A Page Object for interacting with dropdown menus in the web application. 129 | - Includes methods for selecting items from dropdowns and checking the current selection. 130 | 131 | - **`HomePage`** 132 | - A Page Object for the main or home page of the web application. 133 | - Contains methods for interacting with elements on the home page. 134 | 135 | - **`NavigationPage`** 136 | - A Page Object for handling navigation-related elements or interactions on the site (like menus or sidebars). 137 | 138 | --- 139 | 140 | ### `hooks` 141 | 142 | - **`Hooks`** 143 | - A Cucumber hook class that initializes or terminates the test execution. 144 | - Contains methods annotated with `@Before` and `@After` to set up or tear down things like WebDriver instances before and after the tests. 145 | 146 | --- 147 | 148 | ### `steps.browseragnosticfeatures` 149 | 150 | - **`DialogBoxStepDefinitions`** 151 | - Step definition class that defines the steps for handling dialog boxes in tests. 152 | - Steps might include clicking buttons on the dialog, verifying alert messages, etc. 153 | 154 | - **`InfiniteScrollingStepDefinitions`** 155 | - Step definition class that defines steps for interacting with infinite scrolling pages, such as scrolling until an element is visible. 156 | 157 | --- 158 | 159 | ### `steps.pageobjectmodel` 160 | 161 | - **`LoginFormStepDefinitions`** 162 | - Step definition class with steps to interact with the login form (filling out username/password fields and submitting the form). 163 | 164 | --- 165 | 166 | ### `steps.webdriverfundamentals` 167 | 168 | - **`DragAndDropStepDefinitions`** 169 | - Step definition class for defining actions related to drag-and-drop functionality. 170 | 171 | - **`DropDownMenuStepDefinitions`** 172 | - Step definition class that includes steps for interacting with dropdown menus in the tests. 173 | 174 | - **`HomeStepDefinitions`** 175 | - Step definition class for testing interactions on the home page. 176 | 177 | - **`NavigationStepDefinitions`** 178 | - Step definition class for interactions related to navigation elements. 179 | 180 | - **`WebFormComponentsStepDefinitions`** 181 | - Step definition class for interacting with web form components like input fields, buttons, and dropdowns. 182 | 183 | --- 184 | 185 | ### `RunCucumberTest` 186 | - The test runner class that uses Cucumber to run the tests. 187 | - Defines the location of feature files and configures reporting options for the test execution. 188 | 189 | 190 | ## Test Reports 191 | 192 | After running the tests, you can find the test execution reports in the `target` directory. The reports are generated in HTML format, providing a detailed overview of the test results. 193 | 194 | ![Test Report ](https://github.com/NoushinB/Selenium-WebDriver-Java-Testing-Example/blob/master/src/test/resources/files/report.png) 195 | 196 | --- 197 | 198 | ## Test Execution Demo 199 | 200 | 201 | [![Watch the RestAssured-API-Testing DEMO](https://github.com/NoushinB/Selenium-WebDriver-Java-Testing-Example/blob/master/src/test/resources/files/Demo.png?raw=true)](https://youtu.be/USy0EVfLg2s) 202 | 203 | 204 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | SeleniumWebDriverJavaTestingExample 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 15 13 | 15 14 | UTF-8 15 | 7.18.0 16 | 4.24.0 17 | 18 | 19 | 20 | io.cucumber 21 | cucumber-java 22 | ${cucumber.version} 23 | 24 | 25 | io.cucumber 26 | cucumber-junit 27 | ${cucumber.version} 28 | test 29 | 30 | 31 | org.seleniumhq.selenium 32 | selenium-java 33 | ${selenium.version} 34 | 35 | 36 | io.github.bonigarcia 37 | webdrivermanager 38 | 5.9.2 39 | test 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/test/java/RunCucumberTest.java: -------------------------------------------------------------------------------- 1 | import io.cucumber.junit.Cucumber; 2 | import io.cucumber.junit.CucumberOptions; 3 | import org.junit.runner.RunWith; 4 | 5 | @RunWith(Cucumber.class) 6 | @CucumberOptions( 7 | features = "src/test/resources/features", 8 | publish = true, 9 | plugin = {"pretty", "html:target/cucumber-reports.html"}, 10 | tags = "not @todo" 11 | ) 12 | public class RunCucumberTest { 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/core/drivers/DriverManager.java: -------------------------------------------------------------------------------- 1 | package core.drivers; 2 | 3 | 4 | import org.openqa.selenium.WebDriver; 5 | 6 | /** 7 | * Managing web drivers instances for threads 8 | */ 9 | public class DriverManager { 10 | // ThreadLocal to store WebDriver instances for each thread 11 | private static final ThreadLocal driverThread = new ThreadLocal<>(); 12 | 13 | /* 14 | Gets the WebDriver instance for the current thread. 15 | */ 16 | public static WebDriver getDriver() { 17 | return driverThread.get(); 18 | } 19 | 20 | /* 21 | Sets the WebDriver instance for the current thread. 22 | */ 23 | public static void setDriver(WebDriver webDriver) { 24 | driverThread.set(webDriver); 25 | } 26 | 27 | /* 28 | Removes the WebDriver instance for the current thread and quits the browser. 29 | */ 30 | public static void removeDriver() { 31 | WebDriver driver = getDriver(); 32 | if (driver != null) { 33 | driver.quit(); // Close the browser 34 | driverThread.remove(); // Remove the WebDriver instance from the ThreadLocal 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/core/drivers/DriverProvider.java: -------------------------------------------------------------------------------- 1 | package core.drivers; 2 | 3 | import core.library.Constants; 4 | import core.library.PropertyLoader; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | import org.openqa.selenium.chrome.ChromeOptions; 8 | import org.openqa.selenium.firefox.FirefoxDriver; 9 | 10 | import java.time.Duration; 11 | 12 | public class DriverProvider { 13 | private WebDriver driver; 14 | 15 | private final PropertyLoader properties = PropertyLoader.getInstance(); 16 | 17 | /*Returns the WebDriver instance. Initializes it if not already done. 18 | */ 19 | public WebDriver getDriver() { 20 | if (driver == null) { 21 | initializeDriver(); 22 | } 23 | return driver; 24 | } 25 | 26 | /* 27 | Initializes the WebDriver based on the browser type specified in PropertyLoader. 28 | */ 29 | private void initializeDriver() { 30 | String browser = properties.getBrowser(); 31 | 32 | switch (browser.toLowerCase()) { 33 | case Constants.Browser.CHROME: 34 | initializeChromeDriver(); 35 | break; 36 | case Constants.Browser.FIREFOX: 37 | initializeFirefoxDriver(); 38 | break; 39 | default: 40 | throw new IllegalArgumentException("Unsupported browser: " + browser); 41 | } 42 | 43 | driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); 44 | } 45 | 46 | /** 47 | * Initializes the ChromeDriver. 48 | */ 49 | private void initializeChromeDriver() { 50 | // It is already handled in @BeforeAll using WebDriverManager and it will be downloaded automatically 51 | //System.setProperty("webdriver.chrome.driver", "D:/dev/drivers/chromedriver-win64/chromedriver.exe"); 52 | ChromeOptions options = new ChromeOptions(); 53 | options.addArguments("--disable-search-engine-choice-screen"); 54 | driver = new ChromeDriver(options); 55 | } 56 | 57 | /** 58 | * Initializes the FirefoxDriver. 59 | */ 60 | private void initializeFirefoxDriver() { 61 | // System.setProperty("webdriver.gecko.driver", "D:/drivers/geckodriver-v0.34.0-win32/geckodriver.exe"); 62 | driver = new FirefoxDriver(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/core/library/Constants.java: -------------------------------------------------------------------------------- 1 | package core.library; 2 | 3 | import java.time.Duration; 4 | 5 | public class Constants { 6 | public static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(15); 7 | 8 | public static final class Browser { 9 | public static final String CHROME = "chrome"; 10 | public static final String FIREFOX = "firefox"; 11 | // Add other browsers if needed, e.g., Edge, Safari, etc. 12 | } 13 | 14 | public static final class Urls { 15 | public static final String BASE_URL = "https://bonigarcia.dev/selenium-webdriver-java/"; 16 | // Add other URLs if needed 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/core/library/PropertyLoader.java: -------------------------------------------------------------------------------- 1 | package core.library; 2 | 3 | /** 4 | * Singleton class to make sure we will only have one instance during running tests 5 | */ 6 | public class PropertyLoader { 7 | 8 | // Volatile ensures that in a multi-threading environment all threads have the same instance value 9 | private static volatile PropertyLoader instance; 10 | 11 | public static PropertyLoader getInstance() { 12 | if (instance == null) { 13 | // Synchronized ensures that in a multi-threading environment only one thread can modify the instance at a time 14 | synchronized (PropertyLoader.class) { 15 | if (instance == null) { 16 | instance = new PropertyLoader(); 17 | } 18 | } 19 | } 20 | return instance; 21 | } 22 | 23 | /* 24 | Property to save the browser type 25 | */ 26 | private String browser; 27 | 28 | /* 29 | Property to save the base URL 30 | */ 31 | private String baseUrl; 32 | 33 | /** 34 | Browser property getter 35 | @return the browser value 36 | */ 37 | public String getBrowser() { 38 | return browser; 39 | } 40 | 41 | /* 42 | Browser property setter 43 | 44 | @param browser new value for browser 45 | */ 46 | public void setBrowser(String browser) { 47 | this.browser = browser; 48 | } 49 | 50 | /* 51 | Base URL property getter 52 | 53 | @return the baseUrl value 54 | */ 55 | public String getBaseUrl() { 56 | return baseUrl; 57 | } 58 | 59 | /*Base URL property setter 60 | 61 | @param baseUrl new value for baseUrl 62 | */ 63 | public void setBaseUrl(String baseUrl) { 64 | this.baseUrl = baseUrl; 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/test/java/hooks/Hooks.java: -------------------------------------------------------------------------------- 1 | package hooks; 2 | 3 | import core.drivers.DriverManager; 4 | import core.drivers.DriverProvider; 5 | import core.library.Constants; 6 | import core.library.PropertyLoader; 7 | import io.cucumber.java.After; 8 | import io.cucumber.java.AfterAll; 9 | import io.cucumber.java.Before; 10 | import io.cucumber.java.BeforeAll; 11 | import io.github.bonigarcia.wdm.WebDriverManager; 12 | import org.openqa.selenium.WebDriver; 13 | 14 | public class Hooks { 15 | 16 | @BeforeAll 17 | public static void setup() { 18 | // Initialize browsers web drivers 19 | WebDriverManager.chromedriver().setup(); 20 | // WebDriverManager.firefoxdriver().setup(); 21 | // WebDriverManager.edgedriver().setup(); 22 | // WebDriverManager.operadriver().setup(); 23 | // WebDriverManager.iedriver().setup(); 24 | 25 | // Any global setup for web testing 26 | PropertyLoader.getInstance().setBrowser(Constants.Browser.CHROME); 27 | PropertyLoader.getInstance().setBaseUrl(Constants.Urls.BASE_URL); 28 | } 29 | 30 | @Before 31 | public static void beforeTest() { 32 | DriverProvider driverProvider = new DriverProvider(); 33 | WebDriver driver = driverProvider.getDriver(); 34 | DriverManager.setDriver(driver); 35 | } 36 | 37 | @After 38 | public static void afterTest() { 39 | WebDriver driver = DriverManager.getDriver(); 40 | if (driver != null) { 41 | driver.quit(); 42 | } 43 | DriverManager.removeDriver(); 44 | } 45 | 46 | @AfterAll 47 | public static void teardown() { 48 | // Any global cleanup after all tests 49 | } 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/test/java/pages/browseragnosticfeatures/DialogBoxPage.java: -------------------------------------------------------------------------------- 1 | package pages.browseragnosticfeatures; 2 | 3 | import pages.common.BasePage; 4 | import org.openqa.selenium.Alert; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | import org.openqa.selenium.support.ui.ExpectedConditions; 8 | import org.openqa.selenium.support.ui.WebDriverWait; 9 | 10 | import java.time.Duration; 11 | 12 | public class DialogBoxPage extends BasePage { 13 | 14 | // Finding the alert button by its ID 15 | @FindBy(id = "my-alert") 16 | private WebElement launchAlertButton; 17 | 18 | // Finding the confirm button by its ID 19 | @FindBy(id = "my-confirm") 20 | private WebElement launchConfirmButton; 21 | 22 | // Finding the prompt button by its ID 23 | @FindBy(id = "my-prompt") 24 | private WebElement launchPromptButton; 25 | 26 | // Finding the modal button by its ID 27 | @FindBy(id = "my-modal") 28 | private WebElement launchModalButton; 29 | 30 | // Finding the text elements that display the results of confirm, prompt, and modal actions 31 | @FindBy(id = "confirm-text") 32 | private WebElement confirmText; 33 | 34 | @FindBy(id = "prompt-text") 35 | private WebElement promptText; 36 | 37 | @FindBy(id = "modal-text") 38 | private WebElement modalText; 39 | 40 | @FindBy(css = ".modal-title") 41 | private WebElement modalTitle; 42 | 43 | // Modal footer buttons 44 | @FindBy(css = ".modal-footer .btn-secondary") 45 | private WebElement closeModalButton; 46 | 47 | @FindBy(css = ".modal-footer .btn-primary") 48 | private WebElement saveChangesButton; 49 | // 50 | 51 | 52 | // Click a button 53 | private WebElement getButton(String buttonName) { 54 | return switch (buttonName) { 55 | case "Launch alert" -> launchAlertButton; 56 | case "Launch confirm" -> launchConfirmButton; 57 | case "Launch prompt" -> launchPromptButton; 58 | case "Launch modal" -> launchModalButton; 59 | case "Close" -> closeModalButton; 60 | case "Save changes" -> saveChangesButton; 61 | default -> throw new IllegalArgumentException("Invalid button name: " + buttonName); 62 | }; 63 | } 64 | 65 | public void clickOnButton(String buttonName) { 66 | getButton(buttonName).click(); 67 | } 68 | 69 | public String getAlertText() { 70 | // Switch to the alert 71 | Alert alert = driver.switchTo().alert(); 72 | // Get the text of the alert 73 | return alert.getText(); 74 | } 75 | 76 | private Alert waitForAlert() { 77 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20)); 78 | return wait.until(ExpectedConditions.alertIsPresent()); 79 | } 80 | 81 | public void acceptAlert() { 82 | Alert alert = waitForAlert(); 83 | // Optional: Add delay only if required 84 | try { 85 | Thread.sleep(2000); // Add a fixed 2-second delay 86 | } catch (InterruptedException e) { 87 | Thread.currentThread().interrupt(); // Restore interrupted status 88 | throw new RuntimeException("Thread sleep was interrupted", e); 89 | } 90 | alert.accept(); 91 | } 92 | 93 | public void cancelConfirmation() { 94 | Alert alert = waitForAlert(); 95 | alert.dismiss(); 96 | } 97 | 98 | public void typeIntoPromptDialog(String text) { 99 | // Wait for the prompt dialog to appear 100 | Alert alert = waitForAlert(); 101 | 102 | // Enter text into the prompt 103 | alert.sendKeys(text); 104 | 105 | // Accept the prompt (equivalent to clicking "OK") 106 | //alert.accept(); 107 | } 108 | 109 | // Generalized method to retrieve text from any WebElement 110 | public String getMessageText(WebElement messageElement) { 111 | return messageElement.getText(); 112 | } 113 | 114 | public String getConfirmationMessageText() { 115 | return getMessageText(confirmText); 116 | } 117 | 118 | public String getPromptMessageText() { 119 | return getMessageText(promptText); 120 | } 121 | 122 | public String getModalDialogTitle() { 123 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); 124 | wait.until(ExpectedConditions.visibilityOf(modalTitle)); 125 | return modalTitle.getText(); 126 | } 127 | 128 | public String getModalMessageText() { 129 | return getMessageText(modalText); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/test/java/pages/browseragnosticfeatures/InfiniteScrollingPage.java: -------------------------------------------------------------------------------- 1 | package pages.browseragnosticfeatures; 2 | 3 | import pages.common.BasePage; 4 | import org.openqa.selenium.JavascriptExecutor; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | 8 | public class InfiniteScrollingPage extends BasePage { 9 | @FindBy(id = "content") 10 | private WebElement content; 11 | 12 | public boolean isInfiniteScrollContentVisible() { 13 | try { 14 | return content.isDisplayed(); 15 | } catch (Exception e) { 16 | return false; 17 | } 18 | } 19 | 20 | /** 21 | * Scrolls to the bottom of the content area using JavaScript. 22 | */ 23 | public void scrollToBottom() { 24 | try { 25 | JavascriptExecutor js = (JavascriptExecutor) driver; 26 | 27 | boolean isScrollable = (Boolean) js.executeScript( 28 | "return arguments[0].scrollHeight > arguments[0].clientHeight;", content); 29 | 30 | if (isScrollable) { 31 | js.executeScript("arguments[0].scrollTop = arguments[0].scrollHeight;", content); 32 | } else { 33 | js.executeScript("window.scrollTo(0, document.body.scrollHeight);"); 34 | } 35 | 36 | Thread.sleep(1000); // Allow time for dynamic content to load 37 | } catch (Exception e) { 38 | throw new RuntimeException("Unable to scroll to the bottom of the content area.", e); 39 | } 40 | } 41 | 42 | /** 43 | * Checks if new content is loaded dynamically by comparing content size. 44 | * 45 | * @return true if new content is loaded, false otherwise. 46 | */ 47 | public boolean isNewContentLoaded() { 48 | try { 49 | int initialHeight = content.getSize().getHeight(); 50 | scrollToBottom(); 51 | Thread.sleep(1000); // Allow time for dynamic content to load 52 | int newHeight = content.getSize().getHeight(); 53 | return newHeight > initialHeight; 54 | } catch (Exception e) { 55 | return false; 56 | } 57 | } 58 | 59 | /** 60 | * Gets the current height of the content area. 61 | * 62 | * @return the height of the content area. 63 | */ 64 | public int getContentHeight() { 65 | return content.getSize().getHeight(); 66 | } 67 | 68 | /** 69 | * Gets the current page URL. 70 | * 71 | * @return the current URL of the page. 72 | */ 73 | public String getCurrentPageURL() { 74 | return driver.getCurrentUrl(); 75 | } 76 | } -------------------------------------------------------------------------------- /src/test/java/pages/common/BasePage.java: -------------------------------------------------------------------------------- 1 | package pages.common; 2 | 3 | import core.drivers.DriverManager; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.support.PageFactory; 6 | 7 | public class BasePage { 8 | protected WebDriver driver; 9 | 10 | public BasePage() { 11 | this.driver = DriverManager.getDriver(); // Assuming DriverManager is set up to return a WebDriver instance 12 | PageFactory.initElements(driver, this); 13 | } 14 | 15 | public String getCurrentPageURL() { 16 | return driver.getCurrentUrl(); 17 | } 18 | 19 | public void goToUrl(String url) { 20 | driver.get(url); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/pages/pageobjectmodel/LoginFormPage.java: -------------------------------------------------------------------------------- 1 | package pages.pageobjectmodel; 2 | 3 | import pages.common.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | public class LoginFormPage extends BasePage { 8 | 9 | // Finding the username input field by its ID 10 | @FindBy(id = "username") 11 | private WebElement usernameInput; 12 | 13 | // Finding the password input field by its ID 14 | @FindBy(id = "password") 15 | private WebElement passwordInput; 16 | 17 | // Finding the submit button by its tag and class 18 | @FindBy(xpath = "//button[@type='submit' and contains(@class, 'btn-outline-primary')]") 19 | private WebElement submitButton; 20 | 21 | // Finding the invalid credentials alert by its ID 22 | @FindBy(id = "invalid") 23 | private WebElement invalidCredentialsAlert; 24 | 25 | // Finding the success message alert by its ID 26 | @FindBy(id = "success") 27 | private WebElement successMessageAlert; 28 | 29 | 30 | /** 31 | * Method to enter username. 32 | * 33 | * @param username - username that enter into the input field. 34 | */ 35 | public void enterUsername(String username) { 36 | usernameInput.clear(); 37 | usernameInput.sendKeys(username); 38 | } 39 | 40 | /** 41 | * Method to enter password. 42 | * 43 | * @param password - password that enter the input field. 44 | */ 45 | public void enterPassword(String password) { 46 | passwordInput.clear(); 47 | passwordInput.sendKeys(password); 48 | } 49 | 50 | public void clickOnSubmitButton() { 51 | submitButton.click(); 52 | } 53 | 54 | public String getLoginMessage() { 55 | if (isElementDisplayed(successMessageAlert)) { 56 | return successMessageAlert.getText(); 57 | } else if (isElementDisplayed(invalidCredentialsAlert)) { 58 | return invalidCredentialsAlert.getText(); 59 | } 60 | return "No message displayed"; 61 | } 62 | 63 | private boolean isElementDisplayed(WebElement element) { 64 | try { 65 | return element.isDisplayed(); 66 | } catch (Exception e) { 67 | return false; // Handle cases where the element is not found or not visible 68 | } 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/pages/webDriverFundamentals/DragAndDropPage.java: -------------------------------------------------------------------------------- 1 | package pages.webDriverFundamentals; 2 | 3 | import pages.common.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.interactions.Actions; 6 | import org.openqa.selenium.support.FindBy; 7 | 8 | public class DragAndDropPage extends BasePage { 9 | private final Actions actions; 10 | @FindBy(id = ("draggable")) 11 | private WebElement draggableElement; 12 | @FindBy(id = ("target")) 13 | private WebElement targetElement; 14 | 15 | public DragAndDropPage() { 16 | actions = new Actions(driver); 17 | } 18 | 19 | 20 | public void dragAndDropElement() { 21 | actions.dragAndDrop(draggableElement, targetElement).build().perform(); 22 | } 23 | 24 | public boolean isElementAtTarget() { 25 | return draggableElement.getLocation().equals(targetElement.getLocation()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/pages/webDriverFundamentals/DropDownMenuPage.java: -------------------------------------------------------------------------------- 1 | package pages.webDriverFundamentals; 2 | 3 | import pages.common.BasePage; 4 | import org.openqa.selenium.NotFoundException; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.interactions.Actions; 7 | import org.openqa.selenium.support.FindBy; 8 | 9 | import java.util.List; 10 | import java.util.Objects; 11 | 12 | public class DropDownMenuPage extends BasePage { 13 | 14 | @FindBy(id = ("my-dropdown-1")) 15 | private WebElement dropDown1; 16 | @FindBy(id = ("my-dropdown-2")) 17 | private WebElement dropDown2; 18 | @FindBy(id = ("my-dropdown-3")) 19 | private WebElement dropDown3; 20 | 21 | @FindBy(xpath = "//ul[@class='dropdown-menu show']//a[@class='dropdown-item']") 22 | private List visibleDropDownMenus1; 23 | @FindBy(xpath = "//ul[@id='context-menu-2']//a[@class='dropdown-item']") 24 | private List visibleDropDownMenus2; 25 | @FindBy(xpath = "//ul[@id='context-menu-3']//a[@class='dropdown-item']") 26 | private List visibleDropDownMenus3; 27 | 28 | public void clickOnButton(String buttonName) { 29 | WebElement dropdownButton = findDropDownButton(buttonName); 30 | Objects.requireNonNull(dropdownButton, "Button not found: " + buttonName); 31 | 32 | Actions actions = new Actions(driver); 33 | 34 | switch (buttonName) { 35 | case "my-dropdown-1" -> dropdownButton.click(); 36 | case "my-dropdown-2" -> actions.contextClick(dropdownButton).perform(); 37 | case "my-dropdown-3" -> actions.doubleClick(dropdownButton).perform(); 38 | } 39 | } 40 | 41 | public void menuItemClick(int menuNumber, String itemText) { 42 | WebElement item = switch (menuNumber) { 43 | case 1 -> findMenuItem(visibleDropDownMenus1, itemText); 44 | case 2 -> findMenuItem(visibleDropDownMenus2, itemText); 45 | case 3 -> findMenuItem(visibleDropDownMenus3, itemText); 46 | default -> throw new IllegalStateException("Unexpected value: " + menuNumber); 47 | }; 48 | Objects.requireNonNull(item, "Menu item not found: " + itemText); 49 | item.click(); 50 | } 51 | 52 | private WebElement findMenuItem(List elements, String itemText) { 53 | return elements.stream().filter(item -> Objects.equals(item.getText(), itemText)).findAny().orElse(null); 54 | } 55 | 56 | private WebElement findDropDownButton(String buttonName) { 57 | return switch (buttonName) { 58 | case "my-dropdown-1" -> dropDown1; 59 | case "my-dropdown-2" -> dropDown2; 60 | case "my-dropdown-3" -> dropDown3; 61 | default -> null; 62 | }; 63 | } 64 | 65 | public boolean areMenuItemsVisible(String buttonName) { 66 | if (Objects.equals(buttonName, "my-dropdown-1")) { 67 | return !visibleDropDownMenus1.isEmpty(); 68 | } else if (Objects.equals(buttonName, "my-dropdown-2")) { 69 | return !visibleDropDownMenus2.isEmpty(); 70 | } else if (Objects.equals(buttonName, "my-dropdown-3")) { 71 | return !visibleDropDownMenus3.isEmpty(); 72 | } else { 73 | throw new NotFoundException("Menu not found"); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/pages/webDriverFundamentals/HomePage.java: -------------------------------------------------------------------------------- 1 | package pages.webDriverFundamentals; 2 | 3 | import pages.common.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | public class HomePage extends BasePage { 8 | 9 | //Chapter 3. WebDriver Fundamentals 10 | @FindBy(xpath = ("//a[text()='Navigation']")) 11 | private WebElement navigationBtn; 12 | @FindBy(xpath = ("//a[text()='Web form']")) 13 | private WebElement webFormBtn; 14 | @FindBy(xpath = ("//a[text()='Dropdown menu']")) 15 | private WebElement dropdownMenuBtn; 16 | @FindBy(xpath = ("//a[text()='Mouse over']")) 17 | private WebElement mouseOverBtn; 18 | @FindBy(xpath = ("//a[text()='Drag and drop']")) 19 | private WebElement dragAndDropBtn; 20 | @FindBy(xpath = ("//a[text()='Draw in canvas']")) 21 | private WebElement drawInCanvasBtn; 22 | @FindBy(xpath = ("//a[text()='Loading images']")) 23 | private WebElement loadingImagesBtn; 24 | @FindBy(xpath = ("//a[text()='Slow calculator']")) 25 | private WebElement slowCalculatorBtn; 26 | 27 | 28 | //Chapter 4. Browser-Agnostic Features 29 | @FindBy(xpath = ("//a[text()='Long page']")) 30 | private WebElement longPageBtn; 31 | @FindBy(xpath = ("//a[text()='Infinite scroll']")) 32 | private WebElement infiniteScrollBtn; 33 | @FindBy(xpath = ("//a[text()='Shadow DOM']")) 34 | private WebElement shadowDOMBtn; 35 | @FindBy(xpath = ("//a[text()='Frames']")) 36 | private WebElement framesBtn; 37 | @FindBy(xpath = ("//a[text()='IFrames']")) 38 | private WebElement iFramesBtn; 39 | @FindBy(xpath = ("//a[text()='Dialog boxes']")) 40 | private WebElement dialogBoxesBtn; 41 | @FindBy(xpath = ("//a[text()='Web storage']")) 42 | private WebElement webStorageBtn; 43 | 44 | 45 | //Chapter 5. Browser-Specific Manipulation 46 | @FindBy(xpath = ("//a[text()='Geolocation']")) 47 | private WebElement geolocationBtn; 48 | @FindBy(xpath = ("//a[text()='Notifications']")) 49 | private WebElement notificationsBtn; 50 | @FindBy(xpath = ("//a[text()='Get user media']")) 51 | private WebElement getUserMediaBtn; 52 | @FindBy(xpath = ("//a[text()='Multilanguage']")) 53 | private WebElement MultilanguageBtn; 54 | @FindBy(xpath = ("//a[text()='Console logs']")) 55 | private WebElement consoleLogsBtn; 56 | 57 | 58 | //Chapter 7. The Page Object Model (POM) 59 | @FindBy(xpath = ("//a[text()='Login form']")) 60 | private WebElement loginFormBtn; 61 | @FindBy(xpath = ("//a[text()='Slow login']")) 62 | private WebElement slowLoginBtn; 63 | 64 | 65 | //Chapter 8. Testing Framework SpecificsChapter 8 66 | @FindBy(xpath = ("//a[text()='Random calculator']")) 67 | private WebElement randomCalculatorBtn; 68 | 69 | 70 | //Chapter 9. Third-Party Integrations 71 | @FindBy(xpath = ("//a[text()='Download files']")) 72 | private WebElement downloadFilesBtn; 73 | @FindBy(xpath = ("//a[text()='A/B Testing']")) 74 | private WebElement ABTestingBtn; 75 | @FindBy(xpath = ("//a[text()='Data types']")) 76 | private WebElement dataTypesBtn; 77 | 78 | public void clickOnButton(String buttonName) { 79 | getButton(buttonName).click(); 80 | } 81 | 82 | private WebElement getButton(String name) { 83 | return switch (name) { 84 | case "Navigation" -> navigationBtn; 85 | case "Web form" -> webFormBtn; 86 | case "Dropdown menu" -> dropdownMenuBtn; 87 | case "Mouse over" -> mouseOverBtn; 88 | default -> null; 89 | }; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/test/java/pages/webDriverFundamentals/NavigationPage.java: -------------------------------------------------------------------------------- 1 | package pages.webDriverFundamentals; 2 | 3 | import pages.common.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | import java.util.Objects; 8 | 9 | public class NavigationPage extends BasePage { 10 | 11 | @FindBy(xpath = ("//a[text()='Previous']")) 12 | private WebElement previousBtn; 13 | @FindBy(xpath = ("//a[text()='1']")) 14 | private WebElement btnOne; 15 | @FindBy(xpath = ("//a[text()='2']")) 16 | private WebElement btnTwo; 17 | @FindBy(xpath = ("//a[text()='3']")) 18 | private WebElement btnThree; 19 | @FindBy(xpath = ("//a[text()='Next']")) 20 | private WebElement nextBtn; 21 | @FindBy(xpath = ("//p[@class='lead']")) 22 | private WebElement textContent; 23 | 24 | public NavigationPage() { 25 | 26 | } 27 | 28 | public String getContentText() { 29 | return textContent.getText(); 30 | } 31 | 32 | public void clickOnButton(String buttonName) { 33 | 34 | Objects.requireNonNull(findNumbereOrStringButton(buttonName)).click(); 35 | } 36 | 37 | public boolean isButtonEnabled(String btnName) { 38 | 39 | return Objects.requireNonNull(findNumbereOrStringButton(btnName)).isEnabled(); 40 | } 41 | 42 | private WebElement findNumbereOrStringButton(String buttonName) { 43 | switch (buttonName) { 44 | case "Previous": 45 | return previousBtn; 46 | case "Next": 47 | return nextBtn; 48 | case "1": 49 | return btnOne; 50 | case "2": 51 | return btnTwo; 52 | case "3": 53 | return btnThree; 54 | default: 55 | return null; 56 | } 57 | } 58 | 59 | } 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/test/java/pages/webDriverFundamentals/webform_components/WebFormComponentsPage.java: -------------------------------------------------------------------------------- 1 | package pages.webDriverFundamentals.webform_components; 2 | 3 | import pages.common.BasePage; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.Keys; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.support.FindBy; 8 | import org.openqa.selenium.support.ui.ExpectedConditions; 9 | import org.openqa.selenium.support.ui.Select; 10 | import org.openqa.selenium.support.ui.WebDriverWait; 11 | 12 | import java.nio.file.Paths; 13 | import java.time.Duration; 14 | import java.util.List; 15 | import java.util.Objects; 16 | 17 | public class WebFormComponentsPage extends BasePage { 18 | 19 | @FindBy(id = "my-text-id") 20 | private WebElement textInput; 21 | @FindBy(xpath = "//input[@name='my-password']") 22 | private WebElement password; 23 | @FindBy(xpath = "//textarea[@name='my-textarea']") 24 | private WebElement textArea; 25 | @FindBy(xpath = "//input[@placeholder='Disabled input']") 26 | private WebElement disabledInput; 27 | @FindBy(xpath = "//input[@name='my-readonly']") 28 | private WebElement readonlyInput; 29 | @FindBy(xpath = "//a[normalize-space()='Return to index']") 30 | private WebElement returnToIndex; 31 | @FindBy(xpath = "//select[@name='my-select']") 32 | private WebElement dropDownSelect; 33 | @FindBy(xpath = "//input[@class='form-control' and @name='my-datalist' and @list='my-options']") 34 | private WebElement dropDownDataList; 35 | @FindBy(xpath = "//input[@name='my-file']") 36 | private WebElement inputFile; 37 | @FindBy(id = "my-check-1") 38 | private WebElement checkedCheckbox; 39 | @FindBy(id = "my-check-2") 40 | private WebElement defaultCheckbox; 41 | @FindBy(id = "my-radio-1") 42 | private WebElement checkedRadio; 43 | @FindBy(id = "my-radio-2") 44 | private WebElement defaultRadio; 45 | @FindBy(xpath = "//button[@type='submit']") 46 | private WebElement submitButton; 47 | @FindBy(xpath = "//input[@name='my-colors']") 48 | private WebElement colorPicker; 49 | @FindBy(xpath = "//input[@name='my-date']") 50 | private WebElement datePicker; 51 | @FindBy(xpath = "//input[@name='my-range']") 52 | private WebElement rangeSlider; 53 | 54 | public void enterTextInput(WebFormTextElement element, String text) { 55 | WebElement textElement = getTextElement(element); 56 | Objects.requireNonNull(textElement, "Text element not found: " + element.name()); 57 | textElement.clear(); 58 | textElement.sendKeys(text); 59 | } 60 | 61 | public String getTextInputValue(WebFormTextElement element) { 62 | WebElement textElement = getTextElement(element); 63 | Objects.requireNonNull(textElement, "Text element not found: " + element.name()); 64 | return textElement.getAttribute("value"); 65 | } 66 | 67 | public boolean isDisabledInputDisabled() { 68 | return !disabledInput.isEnabled(); 69 | } 70 | 71 | public String getDisabledInputMessage() { 72 | return disabledInput.getAttribute("placeholder"); 73 | } 74 | 75 | public String getReadonlyInputValue() { 76 | return readonlyInput.getAttribute("value"); 77 | } 78 | 79 | public boolean isReadonlyInputReadonly() { 80 | return readonlyInput.getAttribute("readonly") != null; 81 | } 82 | 83 | public void clickReturnToIndex() { 84 | returnToIndex.click(); 85 | } 86 | 87 | // Attempt to change the value of the readonly input field and verify it remains unchanged 88 | public boolean isReadonlyInputUnchangedAfterAttempt() { 89 | String initialValue = getReadonlyInputValue(); 90 | 91 | // Attempt to modify the field (this will not actually change the value) 92 | readonlyInput.sendKeys("New Value"); 93 | 94 | // Verify that the value remains the same 95 | return initialValue.equals(getReadonlyInputValue()); 96 | } 97 | 98 | private WebElement getTextElement(WebFormTextElement element) { 99 | if (element == WebFormTextElement.TEXT) { 100 | return textInput; 101 | } else if (element == WebFormTextElement.TEXT_AREA) { 102 | return textArea; 103 | } else if (element == WebFormTextElement.PASSWORD) { 104 | return password; 105 | } 106 | return null; 107 | } 108 | 109 | public void clickOnDropDownButton() { 110 | dropDownSelect.click(); 111 | } 112 | 113 | public void menuItemClick(String itemText) { 114 | Select select = new Select(dropDownSelect); 115 | select.selectByVisibleText(itemText); 116 | } 117 | 118 | public String getDropDownFirstSelectedOptionText() { 119 | Select select = new Select(dropDownSelect); 120 | return select.getFirstSelectedOption().getText(); 121 | } 122 | 123 | public void enterTextInDatalist(String query) { 124 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); 125 | wait.until(ExpectedConditions.visibilityOf(dropDownDataList)); // Wait for the input field to be visible 126 | dropDownDataList.clear(); 127 | dropDownDataList.sendKeys(query); 128 | } 129 | 130 | public List getSuggestions() { 131 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(60)); 132 | wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//datalist[@id='my-options']"))); 133 | 134 | // Get all the options inside the datalist 135 | List options = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath("//datalist[@id='my-options']/option"))); 136 | 137 | // Debugging: print number of options 138 | System.out.println("Number of options found: " + options.size()); 139 | 140 | return options; 141 | } 142 | 143 | public void selectDatalistOption(String option) { 144 | enterTextInDatalist(option); // Type text to filter options 145 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); 146 | wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//datalist[@id='my-options']/option[@value='" + option + "']"))); 147 | dropDownDataList.sendKeys(Keys.ARROW_DOWN); // Navigate to the first suggestion 148 | dropDownDataList.click(); // Select the highlighted suggestion 149 | } 150 | 151 | public String getDatalistInputValue() { 152 | return dropDownDataList.getAttribute("value"); 153 | } 154 | 155 | public void uploadFile(String filePath) { 156 | String absolutePath = Paths.get(filePath).toAbsolutePath().toString(); 157 | inputFile.sendKeys(absolutePath); 158 | } 159 | 160 | public String getUploadedFileName() { 161 | return inputFile.getAttribute("value"); 162 | } 163 | 164 | 165 | public void checkedCheckboxClick() { 166 | checkedCheckbox.click(); 167 | } 168 | 169 | public boolean isCheckboxChecked() { 170 | return checkedCheckbox.isSelected(); 171 | } 172 | 173 | public void selectRadioButton() { 174 | checkedRadio.click(); 175 | } 176 | 177 | public boolean isRadioButtonSelected() { 178 | return checkedRadio.isSelected(); 179 | } 180 | 181 | public void selectDefaultRadio() { 182 | defaultRadio.click(); 183 | } 184 | 185 | public void selectColorByRgb(int red, int green, int blue) { 186 | Objects.requireNonNull(colorPicker, "Color picker element not found."); 187 | String color = rgbToHex(red, green, blue); 188 | colorPicker.clear(); 189 | colorPicker.sendKeys(color); 190 | } 191 | 192 | /** 193 | * Method to get the current value of the color picker 194 | * @return color picker selected value 195 | */ 196 | public String getSelectedColor() { 197 | Objects.requireNonNull(colorPicker, "Color picker element not found."); 198 | return colorPicker.getAttribute("value"); 199 | } 200 | 201 | /** 202 | * Utility method to convert RGB to Hex 203 | */ 204 | public String rgbToHex(int red, int green, int blue) { 205 | return String.format("#%02x%02x%02x", red, green, blue); 206 | } 207 | 208 | /** 209 | * Sets a specific date in the date picker input. 210 | * 211 | * @param date The date to set in the format YYYY-MM-DD. 212 | */ 213 | public void setDatePickerValue(String date) { 214 | Objects.requireNonNull(date, "Date cannot be null."); 215 | datePicker.clear(); // Clear any existing value in the date picker 216 | datePicker.sendKeys(date); // Input the desired date 217 | datePicker.sendKeys(Keys.TAB); // Tab out to trigger any event listeners 218 | } 219 | /** 220 | * Retrieves the current value displayed in the date picker input. 221 | * 222 | * @return The value of the date picker input. 223 | */ 224 | public String getDatePickerValue() { 225 | return datePicker.getAttribute("value"); 226 | } 227 | /** 228 | * Adjust the range slider to a specific value. 229 | * 230 | * @param value The target value to set for the slider. 231 | */ 232 | public void adjustRangeSliderTo(int value) { 233 | int currentValue = Integer.parseInt(rangeSlider.getAttribute("value")); 234 | int offset = value - currentValue; 235 | 236 | // Simulate range slider adjustment using keyboard actions 237 | for (int i = 0; i < Math.abs(offset); i++) { 238 | if (offset > 0) { 239 | rangeSlider.sendKeys(Keys.ARROW_RIGHT); 240 | } else { 241 | rangeSlider.sendKeys(Keys.ARROW_LEFT); 242 | } 243 | } 244 | } 245 | 246 | /** 247 | * Retrieve the current value of the range slider. 248 | * 249 | * @return The current value of the slider as a String. 250 | */ 251 | public String getRangeSliderValue() { 252 | return rangeSlider.getAttribute("value"); 253 | } 254 | 255 | 256 | 257 | } 258 | -------------------------------------------------------------------------------- /src/test/java/pages/webDriverFundamentals/webform_components/WebFormTextElement.java: -------------------------------------------------------------------------------- 1 | package pages.webDriverFundamentals.webform_components; 2 | 3 | public enum WebFormTextElement { 4 | PASSWORD, 5 | TEXT, 6 | TEXT_AREA, 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/steps/browseragnosticfeatures/DialogBoxStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package steps.browseragnosticfeatures; 2 | 3 | import pages.browseragnosticfeatures.DialogBoxPage; 4 | import io.cucumber.java.en.Then; 5 | import io.cucumber.java.en.When; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | import static org.junit.Assert.assertTrue; 9 | 10 | public class DialogBoxStepDefinitions { 11 | private final DialogBoxPage dialogBoxPage; 12 | 13 | public DialogBoxStepDefinitions() { 14 | dialogBoxPage = new DialogBoxPage(); 15 | } 16 | 17 | @When("the user click the {string} button") 18 | public void the_user_click_the_button(String buttonName) { 19 | dialogBoxPage.clickOnButton(buttonName); 20 | } 21 | 22 | @Then("an alert should appear with the text {string}") 23 | public void an_alert_should_appear_with_the_text(String expectedText) { 24 | String alertText = dialogBoxPage.getAlertText(); 25 | 26 | assertEquals(expectedText, alertText); 27 | } 28 | 29 | @Then("the user accept the alert") 30 | public void the_user_accept_the_alert() { 31 | dialogBoxPage.acceptAlert(); 32 | } 33 | 34 | @When("the user accept the confirmation dialog") 35 | public void the_user_accept_the_confirmation_dialog() { 36 | dialogBoxPage.acceptAlert(); 37 | } 38 | 39 | @Then("the text {string} should appear in the confirmation message area") 40 | public void the_text_should_appear_in_the_confirmation_message_area(String expectedText) { 41 | String actualText = dialogBoxPage.getConfirmationMessageText(); 42 | assertEquals(expectedText, actualText); 43 | } 44 | 45 | @When("the user cancel the confirmation dialog") 46 | public void the_user_cancel_the_confirmation_dialog() { 47 | dialogBoxPage.cancelConfirmation(); 48 | } 49 | 50 | @When("the user type {string} into the prompt dialog") 51 | public void the_user_type_into_the_prompt_dialog(String text) { 52 | dialogBoxPage.typeIntoPromptDialog(text); 53 | } 54 | 55 | @When("the user confirm the prompt dialog") 56 | public void the_user_confirm_the_prompt_dialog() { 57 | dialogBoxPage.acceptAlert(); 58 | } 59 | 60 | @Then("the text {string} should appear in the prompt message area") 61 | public void the_text_should_appear_in_the_prompt_message_area(String expectedText) { 62 | String actualText = dialogBoxPage.getPromptMessageText(); 63 | assertEquals(expectedText, actualText); 64 | } 65 | 66 | @When("the user cancel the prompt dialog") 67 | public void the_user_cancel_the_prompt_dialog() { 68 | dialogBoxPage.cancelConfirmation(); 69 | } 70 | 71 | @Then("the prompt message area should remain empty or display a default state") 72 | public void the_prompt_message_area_should_remain_empty_or_display_a_default_state() { 73 | String actualText = dialogBoxPage.getPromptMessageText(); 74 | 75 | // Define the expected default state (assuming it's an empty string or some default value like "No input") 76 | String defaultState = "You typed: null"; // Update this value if there's a default message in your application 77 | assertTrue("The prompt message area is not empty or in the default state. Found: " + actualText, 78 | actualText.isEmpty() || actualText.equals(defaultState)); 79 | 80 | 81 | } 82 | 83 | @Then("the modal dialog should appear with the title {string}") 84 | public void theModalDialogShouldAppearWithTheTitle(String expectedTitle) { 85 | String actualTitle = dialogBoxPage.getModalDialogTitle(); 86 | assertEquals("The modal dialog title does not match the expected value.", expectedTitle, actualTitle); 87 | } 88 | 89 | 90 | @When("the user click the {string} button in the modal") 91 | public void the_user_click_the_button_in_the_modal(String buttonName) { 92 | dialogBoxPage.clickOnButton(buttonName); 93 | } 94 | 95 | @Then("the text {string} should appear in the modal message area") 96 | public void the_text_should_appear_in_the_modal_message_area(String expectedText) { 97 | String actualText = dialogBoxPage.getModalMessageText(); 98 | assertEquals("The text in the modal message area does not match the expected value.", expectedText, actualText); 99 | } 100 | 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/steps/browseragnosticfeatures/InfiniteScrollingStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package steps.browseragnosticfeatures; 2 | 3 | import pages.browseragnosticfeatures.InfiniteScrollingPage; 4 | import io.cucumber.java.en.And; 5 | import io.cucumber.java.en.Then; 6 | import io.cucumber.java.en.When; 7 | import org.junit.Assert; 8 | 9 | public class InfiniteScrollingStepDefinitions { 10 | 11 | private final InfiniteScrollingPage infiniteScrollingPage; 12 | 13 | public InfiniteScrollingStepDefinitions() { 14 | infiniteScrollingPage = new InfiniteScrollingPage(); 15 | } 16 | 17 | @And("the Infinite scroll section is visible on the page") 18 | public void theSectionIsVisibleOnThePage() { 19 | boolean isVisible = infiniteScrollingPage.isInfiniteScrollContentVisible(); 20 | Assert.assertTrue("The Infinite scroll content is not visible on the page.", isVisible); 21 | } 22 | 23 | @When("the user scrolls to the bottom of the visible content in the Infinite scroll section") 24 | public void theUserScrollsToTheBottomOfTheVisibleContentInTheSection() { 25 | infiniteScrollingPage.scrollToBottom(); 26 | } 27 | 28 | @Then("new content is dynamically loaded") 29 | public void newContentIsDynamicallyLoaded() { 30 | boolean isContentLoaded = infiniteScrollingPage.isNewContentLoaded(); 31 | Assert.assertTrue("New content was not dynamically loaded.", isContentLoaded); 32 | } 33 | 34 | @And("the newly loaded content is appended below the existing content") 35 | public void theNewlyLoadedContentIsAppendedBelowTheExistingContent() { 36 | int initialHeight = infiniteScrollingPage.getContentHeight(); 37 | infiniteScrollingPage.scrollToBottom(); 38 | int newHeight = infiniteScrollingPage.getContentHeight(); 39 | 40 | Assert.assertTrue("The new content was not appended below the existing content.", newHeight > initialHeight); 41 | } 42 | 43 | @And("there should be no full page reload during this process") 44 | public void thereShouldBeNoFullPageReloadDuringThisProcess() { 45 | String initialUrl = infiniteScrollingPage.getCurrentPageURL(); 46 | infiniteScrollingPage.scrollToBottom(); 47 | String currentUrl = infiniteScrollingPage.getCurrentPageURL(); 48 | 49 | Assert.assertEquals("A full page reload occurred during the process.", initialUrl, currentUrl); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/steps/pageobjectmodel/LoginFormStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package steps.pageobjectmodel; 2 | 3 | import pages.pageobjectmodel.LoginFormPage; 4 | import io.cucumber.java.en.Then; 5 | import io.cucumber.java.en.When; 6 | 7 | public class LoginFormStepDefinitions { 8 | 9 | final private LoginFormPage loginFormPage; 10 | 11 | public LoginFormStepDefinitions() { 12 | loginFormPage = new LoginFormPage(); 13 | } 14 | 15 | @When("the user enters {string} in the username field") 16 | public void the_user_enters_in_the_username_field(String userName) { 17 | loginFormPage.enterUsername(userName); 18 | 19 | } 20 | 21 | @When("the user enters {string} in the password field") 22 | public void the_user_enters_in_the_password_field(String password) { 23 | loginFormPage.enterPassword(password); 24 | } 25 | 26 | @When("the user clicks the {string} button") 27 | public void the_user_clicks_the_button(String buttonName) { 28 | if (buttonName.equalsIgnoreCase("submitButton")) { 29 | loginFormPage.clickOnSubmitButton(); 30 | } else { 31 | throw new IllegalArgumentException("Unknown button: " + buttonName); 32 | } 33 | } 34 | 35 | @Then("the user should see {string}") 36 | public void the_user_should_see(String string) { 37 | loginFormPage.getLoginMessage(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/steps/webdriverfundamentals/DragAndDropStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package steps.webdriverfundamentals; 2 | 3 | import pages.webDriverFundamentals.DragAndDropPage; 4 | import io.cucumber.java.en.Given; 5 | import io.cucumber.java.en.Then; 6 | import io.cucumber.java.en.When; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class DragAndDropStepDefinitions { 11 | final private DragAndDropPage dragAndDropPage; 12 | 13 | public DragAndDropStepDefinitions() { 14 | dragAndDropPage = new DragAndDropPage(); 15 | } 16 | 17 | @Given("the user is on the DragAndDrop page") 18 | public void userIsOnTheDragAndDropPage() { 19 | String dropDownMenu = "https://bonigarcia.dev/selenium-webdriver-java/drag-and-drop.html"; 20 | String currentUrl = dragAndDropPage.getCurrentPageURL(); 21 | assertEquals(dropDownMenu, currentUrl); 22 | } 23 | 24 | @When("User drags the draggable element to the target element") 25 | public void user_drags_the_draggable_element_to_the_target_element() { 26 | dragAndDropPage.dragAndDropElement(); 27 | } 28 | 29 | @Then("Draggable element should be at the same location as the target element") 30 | public void draggable_element_should_be_at_the_same_location_as_the_target_element() { 31 | dragAndDropPage.isElementAtTarget(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/steps/webdriverfundamentals/DropDownMenuStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package steps.webdriverfundamentals; 2 | 3 | import pages.webDriverFundamentals.DropDownMenuPage; 4 | import io.cucumber.java.en.And; 5 | import io.cucumber.java.en.Then; 6 | import io.cucumber.java.en.When; 7 | 8 | import static org.junit.Assert.assertTrue; 9 | 10 | public class DropDownMenuStepDefinitions { 11 | final private DropDownMenuPage dropDownMenuPage; 12 | 13 | public DropDownMenuStepDefinitions() { 14 | dropDownMenuPage = new DropDownMenuPage(); 15 | } 16 | 17 | @When("User clicks on the {string} dropdown button") 18 | public void user_clicks_on_dropdown_button(String buttonName) { 19 | dropDownMenuPage.clickOnButton(buttonName); 20 | } 21 | 22 | @Then("the dropdown menu items should be visible for {string}") 23 | public void dropdown_menu_items_should_be_visible(String buttonName) { 24 | assertTrue(dropDownMenuPage.areMenuItemsVisible(buttonName)); 25 | } 26 | 27 | @And("the user selects the {string} item in the dropdown {int}") 28 | public void user_selects_dropdown_item(String itemName, int dropdownNumber) { 29 | dropDownMenuPage.menuItemClick(dropdownNumber, itemName); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/steps/webdriverfundamentals/HomeStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package steps.webdriverfundamentals; 2 | 3 | import core.library.PropertyLoader; 4 | import pages.webDriverFundamentals.HomePage; 5 | import io.cucumber.java.en.Given; 6 | import io.cucumber.java.en.Then; 7 | import io.cucumber.java.en.When; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class HomeStepDefinitions { 12 | final private HomePage homePage; 13 | 14 | public HomeStepDefinitions() { 15 | homePage = new HomePage(); 16 | } 17 | 18 | @Given("the user is on the main page") 19 | public void theUserIsOnTheMainPage() throws InterruptedException { 20 | String url = PropertyLoader.getInstance().getBaseUrl(); 21 | homePage.goToUrl(url); 22 | } 23 | 24 | @Given("the user is on the {string} page") 25 | public void theUserIsOnThePage(String page) throws InterruptedException { 26 | String url = PropertyLoader.getInstance().getBaseUrl() + page; 27 | homePage.goToUrl(url); 28 | } 29 | 30 | @When("the user clicks the button named {string} in Section three") 31 | public void theUserClicksTheButtonNamedInSection(String buttonName) { 32 | homePage.clickOnButton(buttonName); 33 | } 34 | 35 | @Then("the user is navigated to the {string} page") 36 | public void theUserIsNavigatedToThePage(String page) { 37 | String expectedUrl = PropertyLoader.getInstance().getBaseUrl() + page; 38 | String currentUrl = homePage.getCurrentPageURL(); 39 | assertEquals(expectedUrl, currentUrl); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/steps/webdriverfundamentals/NavigationStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package steps.webdriverfundamentals; 2 | 3 | import pages.webDriverFundamentals.NavigationPage; 4 | import io.cucumber.java.en.And; 5 | import io.cucumber.java.en.Then; 6 | import io.cucumber.java.en.When; 7 | 8 | import static org.junit.Assert.*; 9 | 10 | public class NavigationStepDefinitions { 11 | final private NavigationPage navigationPage; 12 | 13 | public NavigationStepDefinitions() { 14 | navigationPage = new NavigationPage(); 15 | } 16 | 17 | @And("And the {string} button is disabled") 18 | public void andTheButtonIsDisabled(String buttonName) { 19 | boolean isEnabled = navigationPage.isButtonEnabled(buttonName); 20 | assertFalse("Button should be disabled", isEnabled); 21 | } 22 | 23 | @When("User clicks the {string} button") 24 | public void userClicksANumberedOrButton(String buttonName) { 25 | navigationPage.clickOnButton(buttonName); 26 | } 27 | 28 | @Then("the {string} button is enabled") 29 | public void theButtonIsEnabled(String buttonName) { 30 | boolean isEnabled = navigationPage.isButtonEnabled(buttonName); 31 | assertTrue("Button should be disabled", isEnabled); 32 | } 33 | 34 | @Then("the page content includes {string}") 35 | public void thePageContentUpdates(String text) { 36 | String fullContentText = navigationPage.getContentText(); 37 | assertTrue(fullContentText.startsWith(text)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/steps/webdriverfundamentals/WebFormComponentsStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package steps.webdriverfundamentals; 2 | 3 | import pages.webDriverFundamentals.HomePage; 4 | import pages.webDriverFundamentals.webform_components.WebFormComponentsPage; 5 | import pages.webDriverFundamentals.webform_components.WebFormTextElement; 6 | import io.cucumber.java.en.And; 7 | import io.cucumber.java.en.Given; 8 | import io.cucumber.java.en.Then; 9 | import io.cucumber.java.en.When; 10 | import org.junit.Assert; 11 | import org.openqa.selenium.WebElement; 12 | 13 | import java.util.List; 14 | 15 | import static org.junit.Assert.*; 16 | 17 | public class WebFormComponentsStepDefinitions { 18 | final private WebFormComponentsPage webFormComponentsPage; 19 | final private HomePage homePage; 20 | 21 | public WebFormComponentsStepDefinitions() { 22 | webFormComponentsPage = new WebFormComponentsPage(); 23 | homePage = new HomePage(); 24 | } 25 | 26 | @When("User enters {string} into the text input field") 27 | public void user_enters_into_the_text_input_field(String text) { 28 | webFormComponentsPage.enterTextInput(WebFormTextElement.TEXT, text); 29 | } 30 | 31 | @Then("the text input field should display {string}") 32 | public void the_text_input_field_should_display(String expectedText) { 33 | String actual = webFormComponentsPage.getTextInputValue(WebFormTextElement.TEXT); 34 | assertEquals(expectedText, actual); 35 | } 36 | 37 | @When("User enters {string} into the password field") 38 | public void user_enters_into_the_password_field(String password) { 39 | webFormComponentsPage.enterTextInput(WebFormTextElement.PASSWORD, password); 40 | } 41 | 42 | @Then("the password field should display the entered {string}") 43 | public void the_password_field_should_display_an_obscured_format_of_the_entered_password(String password) { 44 | String passwordValue = webFormComponentsPage.getTextInputValue(WebFormTextElement.PASSWORD); 45 | assertEquals(password, passwordValue); 46 | 47 | } 48 | 49 | @When("User enters {string} into the textarea") 50 | public void user_enters_into_the_textarea(String text) { 51 | webFormComponentsPage.enterTextInput(WebFormTextElement.TEXT_AREA, text); 52 | } 53 | 54 | @Then("the textarea should display content and includes {string}") 55 | public void the_textarea_should_display(String textContent) { 56 | String actual = webFormComponentsPage.getTextInputValue(WebFormTextElement.TEXT_AREA); 57 | assertEquals(textContent, actual); 58 | } 59 | 60 | @Given("the input field is disabled") 61 | public void the_input_field_is_disabled() { 62 | assertTrue(webFormComponentsPage.isDisabledInputDisabled()); 63 | } 64 | 65 | @Then("the input field displays {string}") 66 | public void theInputFieldDisplays(String expextDisabledInput) { 67 | String actualDisabledInput = webFormComponentsPage.getDisabledInputMessage(); 68 | assertEquals(expextDisabledInput, actualDisabledInput); 69 | } 70 | 71 | @When("the input field is readonly with the value {string}") 72 | public void the_input_field_is_readonly_with_the_value(String expectedValue) { 73 | assertTrue(webFormComponentsPage.isReadonlyInputReadonly()); 74 | assertEquals(expectedValue, webFormComponentsPage.getReadonlyInputValue()); 75 | } 76 | 77 | 78 | @Then("User should not be able to write the value") 79 | public void user_should_not_be_able_to_remove_the_value() { 80 | assertTrue(webFormComponentsPage.isReadonlyInputUnchangedAfterAttempt()); 81 | } 82 | 83 | @When("User clicks on the {string} button") 84 | public void userClicksTheButton(String buttonText) { 85 | if (buttonText.equals("Return to index")) { 86 | webFormComponentsPage.clickReturnToIndex(); 87 | } 88 | } 89 | 90 | @Then("User should be redirected to the {string} page") 91 | public void user_should_be_redirected_to_the_page(String page) throws InterruptedException { 92 | homePage.goToUrl(page); 93 | } 94 | 95 | @When("User clicks on the dropdown menu") 96 | public void userClicksOnTheDropdownMenu() { 97 | webFormComponentsPage.clickOnDropDownButton(); 98 | } 99 | 100 | @And("the user selects the option {string}") 101 | public void theUserSelectsThe(String optionName) { 102 | webFormComponentsPage.menuItemClick(optionName); 103 | } 104 | 105 | @Then("the dropdown menu shows the {string} title") 106 | public void theDropdownMenuItemsShouldBeVisibleForButton(String optionName) { 107 | assertEquals(optionName, webFormComponentsPage.getDropDownFirstSelectedOptionText()); 108 | } 109 | 110 | @When("User types {string} into the datalist input field") 111 | public void user_types_into_the_datalist_input_field(String query) { 112 | webFormComponentsPage.enterTextInDatalist(query); 113 | } 114 | 115 | @Then("the datalist should display matching suggestions") 116 | public void the_datalist_should_display_matching_suggestions() { 117 | List suggestions = webFormComponentsPage.getSuggestions(); 118 | assertFalse("No suggestions found", suggestions.isEmpty()); 119 | } 120 | 121 | @When("User selects {string} from the datalist suggestions") 122 | public void user_selects_from_the_datalist_suggestions(String option) { 123 | webFormComponentsPage.selectDatalistOption(option); 124 | } 125 | 126 | @Then("the input field should display {string}") 127 | public void the_input_field_should_display(String expectedValue) { 128 | String actualValue = webFormComponentsPage.getDatalistInputValue(); 129 | assertEquals(expectedValue, actualValue); 130 | } 131 | 132 | 133 | @When("User selects a file {string} located at {string}") 134 | public void user_selects_a_file_using_the_file_input(String filename, String filePath) { 135 | webFormComponentsPage.uploadFile(filePath); 136 | } 137 | 138 | @Then("the file input should display {string}") 139 | public void the_file_input_should_display(String filename) { 140 | String displayedFileName = webFormComponentsPage.getUploadedFileName(); 141 | Assert.assertTrue("The file input did not display the expected filename", displayedFileName.contains(filename)); 142 | } 143 | 144 | @When("User unchecks the checkbox") 145 | public void user_checks_the_checkbox() { 146 | webFormComponentsPage.checkedCheckboxClick(); 147 | } 148 | 149 | @Then("the checkbox should be unchecked") 150 | public void the_checkbox_should_be_checked() { 151 | Assert.assertFalse(webFormComponentsPage.isCheckboxChecked()); 152 | } 153 | 154 | @When("User checks the checkbox") 155 | public void user_unchecks_the_checkbox() { 156 | webFormComponentsPage.checkedCheckboxClick(); 157 | } 158 | 159 | @Then("the checkbox should be checked") 160 | public void the_checkbox_should_be_unchecked() { 161 | Assert.assertTrue(webFormComponentsPage.isCheckboxChecked()); 162 | } 163 | 164 | @When("User selects the {string} radio button") 165 | public void user_selects_the_radio_button(String string) { 166 | webFormComponentsPage.selectRadioButton(); 167 | } 168 | 169 | @Then("the {string} radio button should be checked") 170 | public void the_radio_button_should_be_checked(String string) { 171 | // Write code here that turns the phrase above into concrete actions 172 | throw new io.cucumber.java.PendingException(); 173 | } 174 | 175 | @Then("other radio buttons should not be selected") 176 | public void other_radio_buttons_should_not_be_selected() { 177 | // Write code here that turns the phrase above into concrete actions 178 | throw new io.cucumber.java.PendingException(); 179 | } 180 | 181 | @When("^User chooses the color \"([^\"]*)\", \"([^\"]*)\", \"([^\"]*)\" from the color picker") 182 | public void userChoosesTheColorFromTheColorPicker(int red, int green, int blue) { 183 | webFormComponentsPage.selectColorByRgb(red, green, blue); 184 | } 185 | 186 | @Then("the color picker should display the color {string}") 187 | public void theColorPickerShouldDisplayTheColor(String expectedColor) { 188 | String actualColor = webFormComponentsPage.getSelectedColor(); 189 | Assert.assertEquals(expectedColor, actualColor); 190 | } 191 | 192 | @When("User selects the date {string} from the date picker") 193 | public void userSelectsTheDateFromTheDatePicker(String date) { 194 | webFormComponentsPage.setDatePickerValue(date); 195 | 196 | } 197 | 198 | @Then("the date picker should display {string}") 199 | public void theDatePickerShouldDisplay(String expectedDate) { 200 | String actualDate = webFormComponentsPage.getDatePickerValue(); 201 | Assert.assertEquals(expectedDate, actualDate); 202 | 203 | } 204 | 205 | @When("User moves the range slider to a value of {string}") 206 | public void userMovesTheRangeSliderToAValueOf(String value) { 207 | int number = Integer.valueOf(value); 208 | webFormComponentsPage.adjustRangeSliderTo(number); 209 | 210 | } 211 | 212 | @Then("the range input should display a value of {string}") 213 | public void theRangeInputShouldDisplayAValueOf(String expectedValue) { 214 | int number = Integer.parseInt(expectedValue); 215 | int actualValue = Integer.parseInt(webFormComponentsPage.getRangeSliderValue()); 216 | Assert.assertEquals(number, actualValue); 217 | 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /src/test/resources/cucumber.properties: -------------------------------------------------------------------------------- 1 | cucumber.publish.enabled=true -------------------------------------------------------------------------------- /src/test/resources/features/browser_agnostic_features/dialogBox.feature: -------------------------------------------------------------------------------- 1 | Feature: Button Functionalities 2 | As a user, I want to interact with various buttons on the page 3 | So that I can confirm their behavior and ensure they function as expected 4 | 5 | Background: 6 | Given the user is on the "dialog-boxes.html" page 7 | 8 | Scenario: Verify the alert button displays an alert with the correct message 9 | When the user click the "Launch alert" button 10 | Then an alert should appear with the text "Hello world!" 11 | And the user accept the alert 12 | 13 | Scenario: Verify the confirm button updates the message when accepted 14 | When the user click the "Launch confirm" button 15 | And the user accept the confirmation dialog 16 | Then the text "You chose: true" should appear in the confirmation message area 17 | 18 | Scenario: Verify the confirm button updates the message when canceled 19 | When the user click the "Launch confirm" button 20 | And the user cancel the confirmation dialog 21 | Then the text "You chose: false" should appear in the confirmation message area 22 | 23 | Scenario: Verify the prompt button updates the message with user input 24 | When the user click the "Launch prompt" button 25 | And the user type "Noushin" into the prompt dialog 26 | And the user confirm the prompt dialog 27 | Then the text "You typed: Noushin" should appear in the prompt message area 28 | 29 | Scenario: Verify the prompt button updates the message when prompt is canceled 30 | When the user click the "Launch prompt" button 31 | And the user cancel the prompt dialog 32 | Then the prompt message area should remain empty or display a default state 33 | 34 | Scenario: Verify the modal dialog updates the message when closed 35 | When the user click the "Launch modal" button 36 | Then the modal dialog should appear with the title "Modal title" 37 | When the user click the "Close" button in the modal 38 | Then the text "You chose: Close" should appear in the modal message area 39 | 40 | Scenario: Verify the modal dialog updates the message when changes are saved 41 | When the user click the "Launch modal" button 42 | Then the modal dialog should appear with the title "Modal title" 43 | When the user click the "Save changes" button in the modal 44 | Then the text "You chose: Save changes" should appear in the modal message area 45 | -------------------------------------------------------------------------------- /src/test/resources/features/browser_agnostic_features/infiniteScrolling.feature: -------------------------------------------------------------------------------- 1 | Feature: Infinite Scroll Functionality 2 | 3 | Background: 4 | Given the user is on the "infinite-scroll.html" page 5 | 6 | Scenario: Verify new content loads dynamically on infinite scroll 7 | 8 | And the Infinite scroll section is visible on the page 9 | When the user scrolls to the bottom of the visible content in the Infinite scroll section 10 | Then new content is dynamically loaded 11 | And the newly loaded content is appended below the existing content 12 | And there should be no full page reload during this process -------------------------------------------------------------------------------- /src/test/resources/features/page_object _model/loginForm.feature: -------------------------------------------------------------------------------- 1 | Feature: Login Functionality 2 | As a user, I want to log in using valid credentials 3 | So that I can access the secure area of the website 4 | 5 | Background: 6 | Given the user is on the "login-form.html" page 7 | 8 | Scenario Outline: User attempts to log in with different credentials 9 | When the user enters "" in the username field 10 | And the user enters "" in the password field 11 | And the user clicks the "submitButton" button 12 | Then the user should see "" 13 | 14 | Examples: 15 | | username | password | message | 16 | | user | user | Login successful | 17 | | admin | admin | Invalid credentials | 18 | | test | pass123 | Invalid credentials | 19 | | | user | Invalid credentials | 20 | | user | | Invalid credentials | 21 | -------------------------------------------------------------------------------- /src/test/resources/features/webdriver_fundamental/dragAndDrop.feature: -------------------------------------------------------------------------------- 1 | Feature: DragAndDrop Page 2 | 3 | Background: 4 | Given the user is on the "drag-and-drop.html" page 5 | 6 | Scenario: Verify Drag and Drop to Target 7 | When User drags the draggable element to the target element 8 | Then Draggable element should be at the same location as the target element -------------------------------------------------------------------------------- /src/test/resources/features/webdriver_fundamental/dropdown_menu.feature: -------------------------------------------------------------------------------- 1 | Feature: Dropdown Menu Interaction 2 | 3 | Background: 4 | Given the user is on the "dropdown-menu.html" page 5 | 6 | Scenario Outline: User interacts with dropdown menus 7 | When User clicks on the "" dropdown button 8 | Then the dropdown menu items should be visible for "" 9 | Examples: 10 | | button_name | 11 | | my-dropdown-1 | 12 | | my-dropdown-2 | 13 | | my-dropdown-3 | 14 | 15 | 16 | Scenario Outline: User selects an item in the first dropdown 17 | When User clicks on the "" dropdown button 18 | And the dropdown menu items should be visible for "" 19 | Then the user selects the "" item in the dropdown 20 | Examples: 21 | | button_name | item_name | dropdown_number | 22 | | my-dropdown-1 | Action | 1 | 23 | | my-dropdown-1 | Another action | 1 | 24 | | my-dropdown-2 | Something else here | 2 | 25 | | my-dropdown-3 | Separated link | 3 | 26 | -------------------------------------------------------------------------------- /src/test/resources/features/webdriver_fundamental/home.feature: -------------------------------------------------------------------------------- 1 | Feature: Home 2 | 3 | Background: 4 | Given the user is on the main page 5 | 6 | Scenario Outline: Click the button to navigate to the specific page related to that content. 7 | When the user clicks the button named "" in Section three 8 | Then the user is navigated to the "" page 9 | 10 | Examples: 11 | | button_name | target_page | 12 | | Navigation | navigation1.html | 13 | | Web form | web-form.html | 14 | | Dropdown menu | dropdown-menu.html | 15 | | Mouse over | mouse-over.html | 16 | -------------------------------------------------------------------------------- /src/test/resources/features/webdriver_fundamental/navigation_page.feature: -------------------------------------------------------------------------------- 1 | Feature: Navigation Page 2 | 3 | Background: 4 | Given the user is on the "navigation1.html" page 5 | 6 | Scenario Outline: Click on a Button 7 | When User clicks the "" button 8 | Then the "Previous" button is enabled 9 | 10 | Examples: 11 | | button_name | 12 | | 1 | 13 | | 2 | 14 | | 3 | 15 | | Next | 16 | 17 | 18 | Scenario Outline: The page content updates 19 | When User clicks the "" button 20 | Then the page content includes "" 21 | 22 | Examples: 23 | | button_name | text | 24 | | 1 | Lorem | 25 | | 2 | Ut | 26 | | 3 | Excepteur | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/features/webdriver_fundamental/webFormComponents.feature: -------------------------------------------------------------------------------- 1 | Feature: Web Form Components 2 | 3 | Background: 4 | Given the user is on the "web-form.html" page 5 | 6 | 7 | # Scenario for Text Input 8 | Scenario Outline: Entering text into a text input field 9 | When User enters "" into the text input field 10 | Then the text input field should display "" 11 | 12 | Examples: 13 | | text | 14 | | QA Automation | 15 | 16 | 17 | # Scenario for Password 18 | Scenario Outline: 19 | When User enters "" into the password field 20 | Then the password field should display the entered "" 21 | 22 | Examples: 23 | | password | 24 | | SecurePassword1 | 25 | | MyP@ssw0rd | 26 | | Temp1234 | 27 | 28 | # Scenario for Textarea 29 | Scenario Outline: Entering text into a textarea 30 | When User enters "" into the textarea 31 | Then the textarea should display content and includes "" 32 | 33 | Examples: 34 | | text | 35 | | This is a multiline text input. | 36 | | Example of a longer text block. | 37 | | Short note. | 38 | 39 | # Scenario for Disabled Input 40 | Scenario: Attempting to enter text into a disabled input field 41 | When the input field is disabled 42 | Then the input field displays "Disabled input" 43 | 44 | # Scenario for Readonly Input 45 | Scenario: Viewing and attempting to change a readonly input field 46 | When the input field is readonly with the value "Readonly input" 47 | Then User should not be able to write the value 48 | 49 | 50 | 51 | # Scenario for Return to Index 52 | Scenario: Returning to the index page 53 | When User clicks on the "Return to index" button 54 | Then User should be redirected to the "https://bonigarcia.dev/selenium-webdriver-java/index.html" page 55 | 56 | # Scenario for Dropdown (Select) 57 | Scenario Outline: Selecting an option from a dropdown menu 58 | When User clicks on the dropdown menu 59 | And the user selects the option "