├── .gitignore ├── MIT-LICENSE.txt ├── README.md ├── pom.xml └── src ├── main ├── java │ └── appUnderTest │ │ └── AndroidCalculator.apk └── resources │ └── demo │ ├── demo.png │ └── readme-img.png └── test ├── java └── info │ └── seleniumcucumber │ ├── RunnerTest.java │ ├── annotations │ └── PageObject.java │ ├── pages │ ├── AbstractPage.java │ └── LoginPage.java │ ├── steps │ ├── Hooks.java │ ├── LoginSteps.java │ └── PredefinedStepDefinitions.java │ └── utils │ ├── AssertionMethods.java │ ├── BaseTest.java │ ├── ClickElementsMethods.java │ ├── ConfigurationMethods.java │ ├── Constants.java │ ├── DriverManager.java │ ├── DriverWait.java │ ├── ErrorHandlingMethods.java │ ├── InputMethods.java │ ├── JavascriptHandlingMethods.java │ ├── MiscMethods.java │ ├── NavigateMethods.java │ ├── ProgressMethods.java │ ├── SauceLabsFileManager.java │ ├── ScreenShotMethods.java │ ├── SelectElementByType.java │ ├── TestCaseFailed.java │ ├── Transformer.java │ ├── TypeRegistryConfiguration.java │ └── expectedConditions │ ├── ClickabilityOfElement.java │ ├── ClickabilityOfElementByLocator.java │ ├── InvisibilityOfElement.java │ ├── InvisibilityOfElementByLocator.java │ ├── VisibilityOfElement.java │ └── VisibilityOfElementByLocator.java └── resources ├── allure.properties ├── configs ├── browserstack.properties ├── browserstack_android7_chrome.properties ├── browserstack_win10_chrome.properties ├── local_android_app_nexus5.properties ├── local_android_nexus5.properties ├── saucelab.properties ├── saucelab_android6_chrome.properties ├── saucelab_android_app.properties ├── saucelab_android_app_nexus.properties ├── saucelab_android_chrome.properties └── saucelab_windows_chrome52.properties ├── extent.properties ├── extent.xml └── features └── my_first.feature /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea 3 | *.iml 4 | errorShots 5 | screenShots 6 | .allure 7 | allure-results/ -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 BrowserStack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Selenium-Cucumber-Java 2 | 3 | This repository contains a collection of sample projects and libraries that demonstrate how to use `selenium-cucumber-java`, a BDD (Behavior-Driven Development) framework with Cucumber (v 3.0.0) and Java. The projects showcase automation script development and utilize various reporters such as Allure, HTML, and JSON. Additionally, it offers the ability to capture screenshots for tests and generate error shots for failed test cases. 4 | 5 | ### Installation & Prerequisites 6 | 7 | 1. JDK 1.8+ (Ensure that the Java class path is properly set) 8 | 2. Maven (Ensure that the .m2 class path is properly set) 9 | 3. Eclipse IDE 10 | 4. Required Eclipse Plugins: 11 | - Maven 12 | - Cucumber 13 | 5. Browser driver (Ensure that you have the appropriate browser driver for your desired browser and that the class path is correctly configured) 14 | 15 | ## Framework Setup 16 | 17 | To set up the framework, you can either fork or clone the repository from [here](https://github.com/amiya-pattnaik/selenium-cucumber-java), or download the ZIP file and set it up in your local workspace. 18 | 19 | ## Running Sample Tests 20 | 21 | Access the CLI of your operating system (e.g., iTerm for macOS or PowerShell for Windows) and navigate to the project directory. Then, run the following command to execute the features: `mvn clean test`. 22 | By default, this command will invoke the Firefox browser and execute the tests. 23 | 24 | - To run features on a specific browser, use the command: `mvn test "-Dbrowser=browser_name"`. Replace `browser_name` with one of the following options: Firefox, Chrome, Safari, etc. Ensure that the browser's driver files are present and specified in the system variables. 25 | // Need to find out if Internet Explorer is supported or this should be updated to Edge, then update details around IE to Edge 26 | 27 | Please note that browser drivers are not included as part of this framework. The reason for this is that the version of Selenium browser drivers varies based on the browser version you are using, as well as the Selenium server version. 28 | 29 | - To run a specific feature file among multiple feature files, use the command: `mvn test -Dcucumber.options="classpath:features/my_first.feature"`. 30 | 31 | ## Reporters 32 | 33 | Once you have run your tests, you can generate various types of reports. This `selenium-cucumber-java` framework utilizes different test reporters to communicate pass/failure information. 34 | 35 | ## Reporting 36 | 37 | ### Allure Report 38 | 39 | To generate an Allure report, you can use one of the following commands: 40 | 41 | - `mvn allure:serve`: This command generates the report in the temp folder and opens a web server with the results in your default browser. 42 | 43 | A typical Allure report will look like this: 44 | 45 | ![Allure Report](https://github.com/amiya-pattnaik/selenium-cucumber-java/blob/master/src/main/resources/demo/readme-img.png) 46 | 47 | - `mvn allure:report`: This command generates the report in the `target/site/allure-maven/index.html` directory, allowing you to view it locally. 48 | 49 | ### HTML Report 50 | 51 | To generate an HTML report, use the following command: `mvn test -Dcucumber.options="--plugin html:target/result.html"`. 52 | This command generates an HTML report, and you can find it at `target/result.html`. 53 | 54 | ### JSON Report 55 | 56 | To generate a JSON report, use the following command: `mvn test -Dcucumber.options="--plugin json:target/result.json"`. 57 | This command generates a JSON report, and you can find it at `target/result.json`. 58 | 59 | ### Extent Spark Reports 60 | 61 | The framework utilizes the [Spark Reports Framework](http://www.extentreports.com/docs/versions/4/java/spark-reporter.html) to generate HTML test reports. Here is an example of a report generated by the Extent Reports open-source library: 62 | 63 | ![Extent Spark Report](https://github.com/amiya-pattnaik/selenium-cucumber-java/blob/master/src/main/resources/demo/demo.png) 64 | 65 | ## BDD Automation with Cucumber-Java and Page Objects 66 | 67 | In this repository, we encourage the use of Behavior-Driven Development (BDD) with Cucumber and Java to develop automation scripts. We provide predefined Step Definitions packaged under `/steps/Commonsteps.java` to help you accelerate your automation development. These Step Definitions support commonly used helper methods and can be customized according to your needs. 68 | 69 | Tests are written in the Cucumber framework using the Gherkin syntax. If you're new to Gherkin and Cucumber, you can find more information at [cucumber.io/docs/reference](https://cucumber.io/docs/reference). A typical test will have a structure similar to this: 70 | 71 | ```gherkin 72 | Feature: Performing a Google Search 73 | 74 | As a user on the Google search page 75 | I want to search for Selenium-Webdriver 76 | Because I want to learn more about it 77 | 78 | Background: 79 | Given I am on the search page 80 | 81 | Scenario: Performing a search operation 82 | When I enter "Selenium Webdriver" into the search box 83 | And I click the search button 84 | Then I should see a list of search results 85 | 86 | Scenario Outline: Performing a search operation with test data from a data table 87 | When I enter into the search box 88 | And I click the search button 89 | Then I should see a list of search results 90 | 91 | Examples: 92 | | searchItem | 93 | | "Selenium Webdriver" | 94 | ``` 95 | 96 | ## The Page Object Design Pattern 97 | 98 | To better organize your test code and make it more maintainable, we recommend using the Page Object Design Pattern. With this pattern, the UI elements of your web application are modeled as objects within the test code. This approach reduces code duplication and allows easy updates if the UI changes. Writing and maintaining test automation can be challenging, especially when it comes to keeping selectors (classes, IDs, or XPath, etc.) up to date with the latest code changes. The Page Object pattern provides a solution by centralizing these selectors in separate .java files, where you can manage them along with the associated methods. 99 | 100 | By using the Page Object pattern, your test files will only call the test methods, while the selectors and reusable methods reside in the corresponding Page Objects. This approach helps maintain a separation of concerns and ensures that when a test fails, it fails on an individual step. If a selector becomes invalid, updating it in the Page Object file can fix multiple failing tests that rely on the same selector. 101 | 102 | Implementing the Page Object pattern promotes maintainable and scalable test automation code, making it easier to adapt to UI changes and keep your code DRY (Don't Repeat Yourself). 103 | 104 | ## Contribution 105 | 106 | We welcome and encourage contributions from the community to make this project even better! If you have ideas, bug fixes, or new features to contribute, follow the steps below: 107 | 108 | 1. Fork the project repository to your own GitHub account. 109 | 2. Create a new branch for your changes and switch to it. 110 | 3. Make the necessary changes, additions, or bug fixes in your branch. 111 | 4. Write clear and concise commit messages to explain the purpose of each change. 112 | 5. If your contribution introduces new functionality, consider adding tests to ensure its robustness. 113 | 6. Once your changes are ready, submit a pull request (PR) to the original repository. 114 | 7. In the PR description, provide a detailed explanation of the changes you made, including any relevant context or background information. 115 | 8. The project maintainers will review your PR, provide feedback, and collaborate with you to refine the changes if needed. 116 | 9. Once approved, your contribution will be merged into the main project. 117 | 10. Celebrate your successful contribution! 🎉 118 | 119 | We encourage respectful and constructive interactions among contributors. Your time and effort in improving this project are highly valued, and we are excited to see your contributions. Together, let's create something amazing! 120 | 121 | ### Licensing 122 | 123 | [MIT](https://github.com/amiya-pattnaik/selenium-cucumber-java/MIT-LICENSE.txt) 124 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | selenium-cucumber-java 5 | selenium-cucumber-java 6 | 1.0.2-SNAPSHOT 7 | 8 | 9 | 10 | 1.8.11 11 | 1.7.21 12 | chrome 13 | cloud_config 14 | 15 | 16 | 17 | 18 | https://github.com/amiya-pattnaik 19 | apattnaik 20 | apattnaik 21 | 22 | 23 | https://github.com/cmccarthyIrl 24 | cmccarthy 25 | cmccarthy 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | io.github.bonigarcia 34 | webdrivermanager 35 | 5.0.2 36 | 37 | 38 | 39 | cucumber-java 40 | io.cucumber 41 | 4.8.1 42 | 43 | 44 | 45 | cucumber-junit 46 | io.cucumber 47 | 4.8.1 48 | 49 | 50 | 51 | com.fasterxml.jackson.core 52 | jackson-databind 53 | 2.12.7.1 54 | 55 | 56 | 57 | 58 | junit 59 | junit 60 | 4.13.1 61 | 62 | 63 | 64 | selenium-java 65 | org.seleniumhq.selenium 66 | 3.141.59 67 | 68 | 69 | 70 | org.seleniumhq.selenium 71 | selenium-server 72 | 3.12.0 73 | 74 | 75 | 76 | ngwebdriver 77 | com.paulhammant 78 | 1.0 79 | 80 | 81 | 82 | 83 | io.appium 84 | java-client 85 | 5.0.4 86 | 87 | 88 | 89 | 90 | io.qameta.allure 91 | allure-cucumber4-jvm 92 | 2.10.0 93 | 94 | 95 | 96 | io.qameta.allure 97 | allure-junit4 98 | 2.10.0 99 | 100 | 101 | 102 | 103 | extentreports-cucumber4-adapter 104 | com.aventstack 105 | 1.2.1 106 | 107 | 108 | cucumber-java 109 | io.cucumber 110 | 111 | 112 | cucumber-core 113 | io.cucumber 114 | 115 | 116 | 117 | 118 | 119 | 120 | org.slf4j 121 | slf4j-api 122 | ${slf4j.version} 123 | 124 | 125 | org.slf4j 126 | slf4j-simple 127 | ${slf4j.version} 128 | 129 | 130 | 131 | 132 | 133 | 134 | org.apache.maven.plugins 135 | maven-compiler-plugin 136 | 3.2 137 | 138 | UTF-8 139 | 1.8 140 | 1.8 141 | 142 | 143 | 144 | 145 | 146 | 147 | org.apache.maven.plugins 148 | maven-surefire-plugin 149 | 3.0.0-M5 150 | 151 | 152 | org.aspectj 153 | aspectjweaver 154 | ${aspectj.version} 155 | 156 | 157 | 158 | 159 | **/**/RunnerTest.java 160 | 161 | 162 | -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" 163 | 164 | 165 | 166 | browser 167 | ${browser} 168 | 169 | 170 | cloud_config 171 | ${cloud_config} 172 | 173 | 174 | 175 | 176 | 177 | io.qameta.allure 178 | allure-maven 179 | 2.9 180 | 181 | 182 | 183 | 184 | 185 | 186 | io.qameta.allure 187 | allure-maven 188 | 2.9 189 | 190 | 2.3.5 191 | 192 | 193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /src/main/java/appUnderTest/AndroidCalculator.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amiya-pattnaik/selenium-cucumber-java/8de5b5213352f18b96ededc773f1f053bd8b3235/src/main/java/appUnderTest/AndroidCalculator.apk -------------------------------------------------------------------------------- /src/main/resources/demo/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amiya-pattnaik/selenium-cucumber-java/8de5b5213352f18b96ededc773f1f053bd8b3235/src/main/resources/demo/demo.png -------------------------------------------------------------------------------- /src/main/resources/demo/readme-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amiya-pattnaik/selenium-cucumber-java/8de5b5213352f18b96ededc773f1f053bd8b3235/src/main/resources/demo/readme-img.png -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/RunnerTest.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber; 2 | 3 | 4 | import io.cucumber.junit.Cucumber; 5 | import io.cucumber.junit.CucumberOptions; 6 | import org.junit.runner.RunWith; 7 | 8 | @RunWith(Cucumber.class) 9 | @CucumberOptions( 10 | plugin = { 11 | "pretty", 12 | "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:", 13 | "io.qameta.allure.cucumber4jvm.AllureCucumber4Jvm", 14 | "json:target/reports/cucumber-json-reports/json-report.json", 15 | "html:target/reports/cucumber-html-reports/html-report.html" 16 | }, 17 | glue = {"info.seleniumcucumber.steps" 18 | }, 19 | features = {"classpath:features/my_first.feature"} 20 | ) 21 | public class RunnerTest { 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/annotations/PageObject.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.annotations; 2 | 3 | import org.openqa.selenium.support.FindBy; 4 | import org.openqa.selenium.support.PageFactoryFinder; 5 | import org.springframework.context.annotation.Lazy; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.Target; 11 | 12 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 13 | 14 | @Retention(RUNTIME) 15 | @Target({ElementType.FIELD, ElementType.TYPE}) 16 | @PageFactoryFinder(FindBy.FindByBuilder.class) 17 | @Lazy 18 | @Component 19 | public @interface PageObject { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/pages/AbstractPage.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.pages; 2 | 3 | import info.seleniumcucumber.utils.BaseTest; 4 | import info.seleniumcucumber.utils.DriverManager; 5 | import info.seleniumcucumber.utils.DriverWait; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.support.PageFactory; 8 | 9 | public abstract class AbstractPage implements BaseTest { 10 | 11 | private final DriverManager driverManager = new DriverManager(); 12 | private final DriverWait driverWait = new DriverWait(driverManager); 13 | 14 | protected AbstractPage() { 15 | PageFactory.initElements(driverManager.getDriver(), this); 16 | } 17 | 18 | public WebDriver getDriver() { 19 | return driverManager.getDriver(); 20 | } 21 | 22 | public DriverWait getDriverWait() { 23 | return driverWait; 24 | } 25 | 26 | public void wait(String time) throws InterruptedException { 27 | Thread.sleep(Integer.parseInt(time)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/pages/LoginPage.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.pages; 2 | 3 | import info.seleniumcucumber.annotations.PageObject; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | @PageObject 9 | public class LoginPage extends AbstractPage { 10 | 11 | @FindBy(how = How.ID, using = "flash") 12 | private WebElement MESSAGE; 13 | 14 | public WebElement getMessage() throws NoSuchFieldException { 15 | getDriverWait().waitForElementToLoad(MESSAGE); 16 | return MESSAGE; 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/steps/Hooks.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.steps; 2 | 3 | import io.cucumber.core.api.Scenario; 4 | import io.cucumber.java.After; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.nio.charset.StandardCharsets; 9 | 10 | public class Hooks { 11 | private final Logger log = LoggerFactory.getLogger(Hooks.class); 12 | 13 | @After 14 | public void afterScenario(Scenario scenario) { 15 | endOfTest(scenario); 16 | } 17 | 18 | public void endOfTest(Scenario scenario) { 19 | if (scenario.getStatus() != null && scenario.isFailed()) { 20 | String filename = scenario.getName().replaceAll("\\s+", "_"); 21 | final String featureError = scenario.getId().replaceAll("\\s+", "_").replaceAll(":", "_").split("\\.")[1]; 22 | filename = filename + "_" + featureError; 23 | scenario.embed(filename.getBytes(StandardCharsets.UTF_8), "image/png", filename); 24 | } 25 | 26 | log.info(""); 27 | log.info("=========================================================================="); 28 | log.info("================================Test " + scenario.getStatus().toString() + "==============================="); 29 | log.info("=========================================================================="); 30 | log.info(""); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/steps/LoginSteps.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.steps; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import info.seleniumcucumber.pages.LoginPage; 5 | import io.cucumber.java.en.Given; 6 | import org.junit.Assert; 7 | 8 | public class LoginSteps extends AbstractPage { 9 | 10 | @Given("^I should get logged-in$") 11 | public void should_logged_in() throws NoSuchFieldException { 12 | final LoginPage loginPage = new LoginPage(); 13 | Assert.assertEquals("You logged into a secure area!", loginPage.getMessage().getText().split("\n")[0].trim()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/steps/PredefinedStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.steps; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import info.seleniumcucumber.utils.TestCaseFailed; 5 | import io.cucumber.java.en.Then; 6 | 7 | import java.io.IOException; 8 | 9 | public class PredefinedStepDefinitions extends AbstractPage { 10 | // Navigation Steps 11 | 12 | // Step to navigate to specified URL 13 | @Then("^I navigate to \"([^\"]*)\"$") 14 | public void navigate_to(String link) { 15 | navigationObj.navigateTo(link); 16 | } 17 | 18 | // Step to navigate forward 19 | @Then("^I navigate forward") 20 | public void navigate_forward() { 21 | navigationObj.navigate("forward"); 22 | } 23 | 24 | // Step to navigate backward 25 | @Then("^I navigate back") 26 | public void navigate_back() { 27 | navigationObj.navigate("back"); 28 | } 29 | 30 | // steps to refresh page 31 | @Then("^I refresh page$") 32 | public void refresh_page() { 33 | getDriver().navigate().refresh(); 34 | } 35 | 36 | // Switch between windows 37 | 38 | // Switch to new window 39 | @Then("^I switch to new window$") 40 | public void switch_to_new_window() { 41 | navigationObj.switchToNewWindow(); 42 | } 43 | 44 | // Switch to old window 45 | @Then("^I switch to previous window$") 46 | public void switch_to_old_window() { 47 | navigationObj.switchToOldWindow(); 48 | } 49 | 50 | // Switch to new window by window title 51 | @Then("^I switch to window having title \"(.*?)\"$") 52 | public void switch_to_window_by_title(String windowTitle) throws Exception { 53 | navigationObj.switchToWindowByTitle(windowTitle); 54 | } 55 | 56 | // Close new window 57 | @Then("^I close new window$") 58 | public void close_new_window() { 59 | navigationObj.closeNewWindow(); 60 | } 61 | 62 | // Switch between frame 63 | 64 | // Step to switch to frame by web element 65 | @Then("^I switch to frame having (.+) \"(.*?)\"$") 66 | public void switch_frame_by_element(String method, String value) { 67 | navigationObj.switchFrame(method, value); 68 | } 69 | 70 | // step to switch to main content 71 | @Then("^I switch to main content$") 72 | public void switch_to_default_content() { 73 | navigationObj.switchToDefaultContent(); 74 | } 75 | 76 | // To interact with browser 77 | 78 | // step to resize browser 79 | @Then("^I resize browser window size to width (\\d+) and height (\\d+)$") 80 | public void resize_browser(int width, int heigth) { 81 | navigationObj.resizeBrowser(width, heigth); 82 | } 83 | 84 | // step to maximize browser 85 | @Then("^I maximize browser window$") 86 | public void maximize_browser() { 87 | navigationObj.maximizeBrowser(); 88 | } 89 | 90 | // zoom in/out page 91 | 92 | // steps to zoom in page 93 | @Then("^I zoom in page$") 94 | public void zoom_in() { 95 | navigationObj.zoomInOut("ADD"); 96 | } 97 | 98 | // steps to zoom out page 99 | @Then("^I zoom out page$") 100 | public void zoom_out() { 101 | navigationObj.zoomInOut("SUBTRACT"); 102 | } 103 | 104 | // zoom out webpage till necessary element displays 105 | 106 | // steps to zoom out till element displays 107 | @Then("^I zoom out page till I see element having (.+) \"(.*?)\"$") 108 | public void zoom_till_element_display(String type, String accessName) throws Exception { 109 | miscmethodObj.validateLocator(type); 110 | navigationObj.zoomInOutTillElementDisplay(type, "substract", accessName); 111 | } 112 | 113 | // reset webpage view use 114 | 115 | @Then("^I reset page view$") 116 | public void reset_page_zoom() { 117 | navigationObj.zoomInOut("reset"); 118 | } 119 | 120 | // scroll webpage 121 | 122 | @Then("^I scroll to (top|end) of page$") 123 | public void scroll_page(String to) throws Exception { 124 | navigationObj.scrollPage(to); 125 | } 126 | 127 | // scroll webpage to specific element 128 | 129 | @Then("^I scroll to element having (.+) \"(.*?)\"$") 130 | public void scroll_to_element(String type, String accessName) throws Exception { 131 | miscmethodObj.validateLocator(type); 132 | navigationObj.scrollToElement(type, accessName); 133 | } 134 | 135 | // hover over element 136 | 137 | // Note: Doesn't work on Windows firefox 138 | @Then("^I hover over element having (.+) \"(.*?)\"$") 139 | public void hover_over_element(String type, String accessName) throws Exception { 140 | miscmethodObj.validateLocator(type); 141 | navigationObj.hoverOverElement(type, accessName); 142 | } 143 | 144 | // Assertion steps 145 | 146 | /** 147 | * page title checking 148 | * 149 | * @param present : 150 | * @param title : 151 | */ 152 | @Then("^I should\\s*((?:not)?)\\s+see page title as \"(.+)\"$") 153 | public void check_title(String present, String title) throws TestCaseFailed { 154 | // System.out.println("Present :" + present.isEmpty()); 155 | assertionObj.checkTitle(title, present.isEmpty()); 156 | } 157 | 158 | // step to check element partial text 159 | @Then("^I should\\s*((?:not)?)\\s+see page title having partial text as \"(.*?)\"$") 160 | public void check_partial_text(String present, String partialTextTitle) throws TestCaseFailed { 161 | // System.out.println("Present :" + present.isEmpty()); 162 | assertionObj.checkPartialTitle(partialTextTitle, present.isEmpty()); 163 | } 164 | 165 | // step to check element text 166 | @Then("^element having (.+) \"([^\"]*)\" should\\s*((?:not)?)\\s+have text as \"(.*?)\"$") 167 | public void check_element_text(String type, String accessName, String present, String value) throws Exception { 168 | miscmethodObj.validateLocator(type); 169 | assertionObj.checkElementText(type, value, accessName, present.isEmpty()); 170 | } 171 | 172 | // step to check element partial text 173 | @Then("^element having (.+) \"([^\"]*)\" should\\s*((?:not)?)\\s+have partial text as \"(.*?)\"$") 174 | public void check_element_partial_text(String type, String accessName, String present, String value) 175 | throws Exception { 176 | miscmethodObj.validateLocator(type); 177 | assertionObj.checkElementPartialText(type, value, accessName, present.isEmpty()); 178 | } 179 | 180 | // step to check attribute value 181 | @Then("^element having (.+) \"([^\"]*)\" should\\s*((?:not)?)\\s+have attribute \"(.*?)\" with value \"(.*?)\"$") 182 | public void check_element_attribute(String type, String accessName, String present, String attrb, String value) 183 | throws Exception { 184 | miscmethodObj.validateLocator(type); 185 | assertionObj.checkElementAttribute(type, attrb, value, accessName, present.isEmpty()); 186 | } 187 | 188 | // step to check element enabled or not 189 | @Then("^element having (.+) \"([^\"]*)\" should\\s*((?:not)?)\\s+be (enabled|disabled)$") 190 | public void check_element_enable(String type, String accessName, String present, String state) throws Exception { 191 | miscmethodObj.validateLocator(type); 192 | boolean flag = state.equals("enabled"); 193 | if (!present.isEmpty()) { 194 | flag = !flag; 195 | } 196 | assertionObj.checkElementEnable(type, accessName, flag); 197 | } 198 | 199 | // step to check element present or not 200 | @Then("^element having (.+) \"(.*?)\" should\\s*((?:not)?)\\s+be present$") 201 | public void check_element_presence(String type, String accessName, String present) throws Exception { 202 | miscmethodObj.validateLocator(type); 203 | assertionObj.checkElementPresence(type, accessName, present.isEmpty()); 204 | } 205 | 206 | // step to assert checkbox is checked or unchecked 207 | @Then("^checkbox having (.+) \"(.*?)\" should be (checked|unchecked)$") 208 | public void is_checkbox_checked(String type, String accessName, String state) throws Exception { 209 | miscmethodObj.validateLocator(type); 210 | boolean flag = state.equals("checked"); 211 | assertionObj.isCheckboxChecked(type, accessName, flag); 212 | } 213 | 214 | // steps to assert radio button checked or unchecked 215 | @Then("^radio button having (.+) \"(.*?)\" should be (selected|unselected)$") 216 | public void is_radio_button_selected(String type, String accessName, String state) throws Exception { 217 | miscmethodObj.validateLocator(type); 218 | boolean flag = state.equals("selected"); 219 | assertionObj.isRadioButtonSelected(type, accessName, flag); 220 | } 221 | 222 | // steps to assert option by text from radio button group 223 | // selected/unselected 224 | @Then("^option \"(.*?)\" by (.+) from radio button group having (.+) \"(.*?)\" should be (selected|unselected)$") 225 | public void is_option_from_radio_button_group_selected(String option, String attrb, String type, String accessName, 226 | String state) throws Exception { 227 | miscmethodObj.validateLocator(type); 228 | boolean flag = state.equals("selected"); 229 | assertionObj.isOptionFromRadioButtonGroupSelected(type, attrb, option, accessName, flag); 230 | } 231 | 232 | // steps to check link presence 233 | @Then("^link having text \"(.*?)\" should\\s*((?:not)?)\\s+be present$") 234 | public void check_element_presence(String accessName, String present) throws TestCaseFailed, Exception { 235 | assertionObj.checkElementPresence("linkText", accessName, present.isEmpty()); 236 | } 237 | 238 | // steps to check partail link presence 239 | @Then("^link having partial text \"(.*?)\" should\\s*((?:not)?)\\s+be present$") 240 | public void check_partial_element_presence(String accessName, String present) throws TestCaseFailed, Exception { 241 | assertionObj.checkElementPresence("partialLinkText", accessName, present.isEmpty()); 242 | } 243 | 244 | // step to assert javascript pop-up alert text 245 | @Then("^I should see alert text as \"(.*?)\"$") 246 | public void check_alert_text(String actualValue) throws TestCaseFailed { 247 | assertionObj.checkAlertText(actualValue); 248 | } 249 | 250 | // step to select dropdown list 251 | @Then("^option \"(.*?)\" by (.+) from dropdown having (.+) \"(.*?)\" should be (selected|unselected)$") 252 | public void is_option_from_dropdown_selected(String option, String by, String type, String accessName, String state) 253 | throws Exception { 254 | miscmethodObj.validateLocator(type); 255 | boolean flag = state.equals("selected"); 256 | assertionObj.isOptionFromDropdownSelected(type, by, option, accessName, flag); 257 | } 258 | 259 | // Input steps 260 | 261 | // enter text into input field steps 262 | @Then("^I enter \"([^\"]*)\" into input field having (.+) \"([^\"]*)\"$") 263 | public void enter_text(String text, String type, String accessName) throws Exception { 264 | miscmethodObj.validateLocator(type); 265 | inputObj.enterText(type, text, accessName); 266 | } 267 | 268 | // clear input field steps 269 | @Then("^I clear input field having (.+) \"([^\"]*)\"$") 270 | public void clear_text(String type, String accessName) throws Exception { 271 | miscmethodObj.validateLocator(type); 272 | inputObj.clearText(type, accessName); 273 | } 274 | 275 | // select option by text/value from dropdown 276 | @Then("^I select \"(.*?)\" option by (.+) from dropdown having (.+) \"(.*?)\"$") 277 | public void select_option_from_dropdown(String option, String optionBy, String type, String accessName) 278 | throws Exception { 279 | miscmethodObj.validateLocator(type); 280 | miscmethodObj.validateOptionBy(optionBy); 281 | inputObj.selectOptionFromDropdown(type, optionBy, option, accessName); 282 | } 283 | 284 | // select option by index from dropdown 285 | @Then("^I select (\\d+) option by index from dropdown having (.+) \"(.*?)\"$") 286 | public void select_option_from_dropdown_by_index(String option, String type, String accessName) throws Exception { 287 | miscmethodObj.validateLocator(type); 288 | inputObj.selectOptionFromDropdown(type, "selectByIndex", option, accessName); 289 | } 290 | 291 | // select option by text/value from multiselect 292 | @Then("^I select \"(.*?)\" option by (.+) from multiselect dropdown having (.+) \"(.*?)\"$") 293 | public void select_option_from_multiselect_dropdown(String option, String optionBy, String type, String accessName) 294 | throws Exception { 295 | miscmethodObj.validateLocator(type); 296 | miscmethodObj.validateOptionBy(optionBy); 297 | inputObj.selectOptionFromDropdown(type, optionBy, option, accessName); 298 | } 299 | 300 | // select option by index from multiselect 301 | @Then("^I select (\\d+) option by index from multiselect dropdown having (.+) \"(.*?)\"$") 302 | public void select_option_from_multiselect_dropdown_by_index(String option, String type, String accessName) 303 | throws Exception { 304 | miscmethodObj.validateLocator(type); 305 | inputObj.selectOptionFromDropdown(type, "selectByIndex", option, accessName); 306 | } 307 | 308 | // deselect option by text/value from multiselect 309 | @Then("^I deselect \"(.*?)\" option by (.+) from multiselect dropdown having (.+) \"(.*?)\"$") 310 | public void deselect_option_from_multiselect_dropdown(String option, String optionBy, String type, 311 | String accessName) throws Exception { 312 | miscmethodObj.validateLocator(type); 313 | miscmethodObj.validateOptionBy(optionBy); 314 | inputObj.deselectOptionFromDropdown(type, optionBy, option, accessName); 315 | } 316 | 317 | // deselect option by index from multiselect 318 | @Then("^I deselect (\\d+) option by index from multiselect dropdown having (.+) \"(.*?)\"$") 319 | public void deselect_option_from_multiselect_dropdown_by_index(String option, String type, String accessName) 320 | throws Exception { 321 | miscmethodObj.validateLocator(type); 322 | inputObj.deselectOptionFromDropdown(type, "selectByIndex", option, accessName); 323 | } 324 | 325 | // step to select option from mutliselect dropdown list 326 | /* 327 | * @Then("^I select all options from multiselect dropdown having (.+) \"(.*?)\"$" 328 | * ) public void select_all_option_from_multiselect_dropdown(String 329 | * type,String accessName) throws Exception { 330 | * miscmethod.validateLocator(type); //inputObj. 331 | * //select_all_option_from_multiselect_dropdown(type, access_name) } 332 | */ 333 | 334 | // step to unselect option from mutliselect dropdown list 335 | @Then("^I deselect all options from multiselect dropdown having (.+) \"(.*?)\"$") 336 | public void unselect_all_option_from_multiselect_dropdown(String type, String accessName) throws Exception { 337 | miscmethodObj.validateLocator(type); 338 | inputObj.unselectAllOptionFromMultiselectDropdown(type, accessName); 339 | } 340 | 341 | // check checkbox steps 342 | @Then("^I check the checkbox having (.+) \"(.*?)\"$") 343 | public void check_checkbox(String type, String accessName) throws Exception { 344 | miscmethodObj.validateLocator(type); 345 | inputObj.checkCheckbox(type, accessName); 346 | } 347 | 348 | // uncheck checkbox steps 349 | @Then("^I uncheck the checkbox having (.+) \"(.*?)\"$") 350 | public void uncheck_checkbox(String type, String accessName) throws Exception { 351 | miscmethodObj.validateLocator(type); 352 | inputObj.uncheckCheckbox(type, accessName); 353 | } 354 | 355 | // steps to toggle checkbox 356 | @Then("^I toggle checkbox having (.+) \"(.*?)\"$") 357 | public void toggle_checkbox(String type, String accessName) throws Exception { 358 | miscmethodObj.validateLocator(type); 359 | inputObj.toggleCheckbox(type, accessName); 360 | } 361 | 362 | // step to select radio button 363 | @Then("^I select radio button having (.+) \"(.*?)\"$") 364 | public void select_radio_button(String type, String accessName) throws Exception { 365 | miscmethodObj.validateLocator(type); 366 | inputObj.selectRadioButton(type, accessName); 367 | } 368 | 369 | // steps to select option by text from radio button group 370 | @Then("^I select \"(.*?)\" option by (.+) from radio button group having (.+) \"(.*?)\"$") 371 | public void select_option_from_radio_btn_group(String option, String by, String type, String accessName) 372 | throws Exception { 373 | miscmethodObj.validateLocator(type); 374 | // miscmethodObj.validateOptionBy(optionBy); 375 | inputObj.selectOptionFromRadioButtonGroup(type, option, by, accessName); 376 | } 377 | 378 | // Click element Steps 379 | 380 | // click on web element 381 | @Then("^I click on element having (.+) \"(.*?)\"$") 382 | public void click(String type, String accessName) throws Exception { 383 | miscmethodObj.validateLocator(type); 384 | clickObj.click(type, accessName); 385 | } 386 | 387 | // Forcefully click on element 388 | @Then("^I forcefully click on element having (.+) \"(.*?)\"$") 389 | public void click_forcefully(String type, String accessName) throws Exception { 390 | miscmethodObj.validateLocator(type); 391 | clickObj.clickForcefully(type, accessName); 392 | } 393 | 394 | // double click on web element 395 | @Then("^I double click on element having (.+) \"(.*?)\"$") 396 | public void double_click(String type, String accessValue) throws Exception { 397 | miscmethodObj.validateLocator(type); 398 | clickObj.doubleClick(type, accessValue); 399 | } 400 | 401 | // steps to click on link 402 | @Then("^I click on link having text \"(.*?)\"$") 403 | public void click_link(String accessName) { 404 | clickObj.click("linkText", accessName); 405 | } 406 | 407 | // Step to click on partial link 408 | @Then("^I click on link having partial text \"(.*?)\"$") 409 | public void click_partial_link(String accessName) { 410 | clickObj.click("partialLinkText", accessName); 411 | } 412 | 413 | // Progress methods 414 | 415 | // wait for specific period of time 416 | @Then("^I wait for (\\d+) sec$") 417 | public void wait(String time) throws NumberFormatException, InterruptedException { 418 | progressObj.wait(time); 419 | } 420 | 421 | // wait for specific element to display for specific period of time 422 | @Then("^I wait (\\d+) seconds for element having (.+) \"(.*?)\" to display$") 423 | public void wait_for_ele_to_display(String duration, String type, String accessName) throws Exception { 424 | miscmethodObj.validateLocator(type); 425 | progressObj.waitForElementToDisplay(type, accessName, duration); 426 | } 427 | 428 | // wait for specific element to enable for specific period of time 429 | @Then("^I wait (\\d+) seconds for element having (.+) \"(.*?)\" to be enabled$") 430 | public void wait_for_ele_to_click(String duration, String type, String accessName) throws Exception { 431 | miscmethodObj.validateLocator(type); 432 | progressObj.waitForElementToClick(type, accessName, duration); 433 | } 434 | 435 | // JavaScript handling steps 436 | 437 | // Step to handle java script 438 | @Then("^I accept alert$") 439 | public void handle_alert() { 440 | javascriptObj.handleAlert("accept"); 441 | } 442 | 443 | // Steps to dismiss java script 444 | @Then("^I dismiss alert$") 445 | public void dismiss_alert() { 446 | javascriptObj.handleAlert("dismiss"); 447 | } 448 | 449 | // Screen shot methods 450 | 451 | @Then("^I take screenshot$") 452 | public void take_screenshot() throws IOException { 453 | screenshotObj.takeScreenShot(); 454 | } 455 | 456 | // Configuration steps 457 | 458 | // step to print configuration 459 | @Then("^I print configuration$") 460 | public void print_config() { 461 | configObj.printDesktopConfiguration(); 462 | } 463 | 464 | // @After 465 | // // Take Screen shot only when a scenario is failed 466 | // public final void takeScreenShot(Scenario scenario) { 467 | // if (scenario.isFailed()) { 468 | // TakesScreenshot ts = (TakesScreenshot) driver; 469 | // File srcFile = ts.getScreenshotAs(OutputType.FILE); 470 | // try { 471 | // ScenarioImpl impl = (ScenarioImpl) scenario; 472 | // Collection tags = impl.getSourceTagNames(); 473 | // StringBuilder sb = new StringBuilder(); 474 | // //sb.append("Scenario"); 475 | // for (String t : tags) { 476 | // sb.append("_" + t); 477 | // } 478 | // //String screenshotname = "errorShots/" + impl.getId().replaceAll("\\W", "_"); 479 | // FileUtils.copyFile(srcFile, new File("errorShots/" + impl.getId().replaceAll("\\W", "_") + ".png")); 480 | // } catch (IOException ex) { 481 | // Logger.getLogger(Scenario.class.getName()).log(Level.SEVERE, null, ex); 482 | // } 483 | // } 484 | // } 485 | 486 | // @After 487 | // public final void tearDown() { 488 | // DriverUtil.closeDriver(); 489 | // } 490 | } -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/AssertionMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.ui.ExpectedConditions; 6 | import org.openqa.selenium.support.ui.Select; 7 | 8 | import java.util.List; 9 | 10 | 11 | public class AssertionMethods extends AbstractPage implements BaseTest { 12 | // This file contains assertion methods which are called from 13 | // predefinedStepDefinitions 14 | 15 | private final SelectElementByType selectElementByType = new SelectElementByType(); 16 | // SelectElementByType eleType= new SelectElementByType(); 17 | private WebElement element = null; 18 | 19 | /** 20 | * Method to get page title 21 | * 22 | * @return String 23 | */ 24 | public String getPageTitle() { 25 | return getDriver().getTitle(); 26 | } 27 | 28 | /** 29 | * Method to verify page title 30 | * 31 | * @param title : String : expected title 32 | * @param testCase : Boolean : test case [true or false] 33 | */ 34 | public void checkTitle(String title, boolean testCase) throws TestCaseFailed { 35 | String pageTitle = getPageTitle(); 36 | 37 | if (testCase) { 38 | if (!pageTitle.equals(title)) 39 | throw new TestCaseFailed("Page Title Not Matched, Actual Page Title : " + pageTitle); 40 | } else { 41 | if (pageTitle.equals(title)) 42 | throw new TestCaseFailed("Page Title Matched, Actual Page Title : " + pageTitle); 43 | } 44 | } 45 | 46 | /** 47 | * Method to verify partial page title 48 | * 49 | * @param partialTitle : String : partial title string 50 | * @param testCase : Boolean : test case [true or false] 51 | */ 52 | public void checkPartialTitle(String partialTitle, boolean testCase) throws TestCaseFailed { 53 | String pageTitle = getPageTitle(); 54 | if (testCase) { 55 | if (!pageTitle.contains(partialTitle)) 56 | throw new TestCaseFailed("Partial Page Title Not Present, Actual Page Title : " + pageTitle); 57 | } else { 58 | if (pageTitle.contains(partialTitle)) 59 | throw new TestCaseFailed("Partial Page Title Present, Actual Page Title : " + pageTitle); 60 | } 61 | } 62 | 63 | /** 64 | * Method to get element text 65 | * 66 | * @param accessType : String : Locator type (id, name, class, xpath, css) 67 | * @param accessName : String : Locator value 68 | * @return String 69 | */ 70 | public String getElementText(String accessType, String accessName) { 71 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 72 | return element.getText(); 73 | 74 | } 75 | 76 | /** 77 | * Method to check element text 78 | * 79 | * @param accessType : String : Locator type (id, name, class, xpath, css) 80 | * @param actualValue : String : Expected element text 81 | * @param accessName : String : Locator value 82 | * @param testCase : Boolean : test case [true or false] 83 | */ 84 | public void checkElementText(String accessType, String actualValue, String accessName, boolean testCase) 85 | throws TestCaseFailed { 86 | String elementText = getElementText(accessType, accessName); 87 | 88 | if (testCase) { 89 | if (!elementText.equals(actualValue)) 90 | throw new TestCaseFailed("Text Not Matched"); 91 | } else { 92 | if (elementText.equals(actualValue)) 93 | throw new TestCaseFailed("Text Matched"); 94 | } 95 | } 96 | 97 | /** 98 | * Method to check partial element text 99 | * 100 | * @param accessType : String : Locator type (id, name, class, xpath, css) 101 | * @param actualValue : String : Expected element text 102 | * @param accessName : String : Locator value 103 | * @param testCase : Boolean : test case [true or false] 104 | */ 105 | public void checkElementPartialText(String accessType, String actualValue, String accessName, boolean testCase) 106 | throws TestCaseFailed { 107 | String elementText = getElementText(accessType, accessName); 108 | 109 | if (testCase) { 110 | if (!elementText.contains(actualValue)) 111 | throw new TestCaseFailed("Text Not Matched"); 112 | } else { 113 | if (elementText.contains(actualValue)) 114 | throw new TestCaseFailed("Text Matched"); 115 | } 116 | } 117 | 118 | /** 119 | * Method to return element status - enabled? 120 | * 121 | * @param accessType : String : Locator type (id, name, class, xpath, css) 122 | * @param accessName : String : Locator value 123 | * @return Boolean 124 | */ 125 | public boolean isElementEnabled(String accessType, String accessName) { 126 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 127 | return element.isEnabled(); 128 | } 129 | 130 | /** 131 | * Element enabled checking 132 | * 133 | * @param accessType : String : Locator type (id, name, class, xpath, css) 134 | * @param accessName : String : Locator value 135 | * @param testCase : Boolean : test case [true or false] 136 | */ 137 | public void checkElementEnable(String accessType, String accessName, boolean testCase) throws TestCaseFailed { 138 | boolean result = isElementEnabled(accessType, accessName); 139 | if (testCase) { 140 | if (!result) 141 | throw new TestCaseFailed("Element Not Enabled"); 142 | } else { 143 | if (result) 144 | throw new TestCaseFailed("Element Enabled"); 145 | } 146 | } 147 | 148 | /** 149 | * method to get attribute value 150 | * 151 | * @param accessType : String : Locator type (id, name, class, xpath, css) 152 | * @param accessName : String : Locator value 153 | * @param attributeName : String : attribute name 154 | * @return String 155 | */ 156 | public String getElementAttribute(String accessType, String accessName, String attributeName) { 157 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 158 | return element.getAttribute(attributeName); 159 | } 160 | 161 | /** 162 | * method to check attribute value 163 | * 164 | * @param accessType : String : Locator type (id, name, class, xpath, css) 165 | * @param attributeName : String : attribute name 166 | * @param attributeValue : String : attribute value 167 | * @param accessName : String : Locator value 168 | * @param testCase : Boolean : test case [true or false] 169 | */ 170 | public void checkElementAttribute(String accessType, String attributeName, String attributeValue, String accessName, 171 | boolean testCase) throws TestCaseFailed { 172 | String attrVal = getElementAttribute(accessType, accessName, attributeName); 173 | if (testCase) { 174 | if (!attrVal.equals(attributeValue)) 175 | throw new TestCaseFailed("Attribute Value Not Matched"); 176 | } else { 177 | if (attrVal.equals(attributeValue)) 178 | throw new TestCaseFailed("Attribute Value Matched"); 179 | } 180 | } 181 | 182 | /** 183 | * method to get element status - displayed? 184 | * 185 | * @param accessType : String : Locator type (id, name, class, xpath, css) 186 | * @param accessName : String : Locator value 187 | * @return Boolean 188 | */ 189 | public boolean isElementDisplayed(String accessType, String accessName) { 190 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 191 | return element.isDisplayed(); 192 | } 193 | 194 | /** 195 | * method to check element presence 196 | * 197 | * @param accessType : String : Locator type (id, name, class, xpath, css) 198 | * @param accessName : String : Locator value 199 | * @param testCase : Boolean : test case [true or false] 200 | */ 201 | public void checkElementPresence(String accessType, String accessName, boolean testCase) throws TestCaseFailed { 202 | if (testCase) { 203 | if (!isElementDisplayed(accessType, accessName)) 204 | throw new TestCaseFailed("Element Not Present"); 205 | } else { 206 | try { 207 | if (isElementDisplayed(accessType, accessName)) 208 | throw new Exception("Present"); // since it is negative test 209 | // and we found element 210 | } catch (Exception e) { 211 | if (e.getMessage().equals("Present")) // only raise if it 212 | // present 213 | throw new TestCaseFailed("Element Present"); 214 | } 215 | } 216 | } 217 | 218 | /** 219 | * method to assert checkbox check/uncheck 220 | * 221 | * @param accessType : String : Locator type (id, name, class, xpath, css) 222 | * @param accessName : String : Locator value 223 | * @param shouldBeChecked : Boolean : test case [true or false] 224 | */ 225 | public void isCheckboxChecked(String accessType, String accessName, boolean shouldBeChecked) throws TestCaseFailed { 226 | WebElement checkbox = getDriverWait().waitShort() 227 | .until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 228 | if ((!checkbox.isSelected()) && shouldBeChecked) 229 | throw new TestCaseFailed("Checkbox is not checked"); 230 | else if (checkbox.isSelected() && !shouldBeChecked) 231 | throw new TestCaseFailed("Checkbox is checked"); 232 | } 233 | 234 | /** 235 | * method to assert radio button selected/unselected 236 | * 237 | * @param accessType : String : Locator type (id, name, class, xpath, css) 238 | * @param accessName : String : Locator value 239 | */ 240 | public void isRadioButtonSelected(String accessType, String accessName, boolean shouldBeSelected) 241 | throws TestCaseFailed { 242 | WebElement radioButton = getDriverWait().waitShort() 243 | .until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 244 | if ((!radioButton.isSelected()) && shouldBeSelected) 245 | throw new TestCaseFailed("Radio Button not selected"); 246 | else if (radioButton.isSelected() && !shouldBeSelected) 247 | throw new TestCaseFailed("Radio Button is selected"); 248 | } 249 | 250 | // method to assert option from radio button group is selected/unselected 251 | public void isOptionFromRadioButtonGroupSelected(String accessType, String by, String option, String accessName, 252 | boolean shouldBeSelected) throws TestCaseFailed { 253 | List radioButtonGroup = getDriverWait().waitShort() 254 | .until(ExpectedConditions.presenceOfAllElementsLocatedBy(selectElementByType.getelementbytype(accessType, accessName))); 255 | 256 | for (WebElement rb : radioButtonGroup) { 257 | if (by.equals("value")) { 258 | if (rb.getAttribute("value").equals(option)) { 259 | if ((!rb.isSelected()) && shouldBeSelected) 260 | throw new TestCaseFailed("Radio Button not selected"); 261 | else if (rb.isSelected() && !shouldBeSelected) 262 | throw new TestCaseFailed("Radio Button is selected"); 263 | } 264 | } else if (rb.getText().equals(option)) { 265 | if ((!rb.isSelected()) && shouldBeSelected) 266 | throw new TestCaseFailed("Radio Button not selected"); 267 | else if (rb.isSelected() && !shouldBeSelected) 268 | throw new TestCaseFailed("Radio Button is selected"); 269 | } 270 | } 271 | } 272 | 273 | /** 274 | * method to get javascript pop-up alert text 275 | * 276 | * @return String 277 | */ 278 | public String getAlertText() { 279 | return getDriver().switchTo().alert().getText(); 280 | } 281 | 282 | /** 283 | * method to check javascript pop-up alert text 284 | * 285 | * @param text : String : Text to verify in Alert 286 | * @throws TestCaseFailed 287 | */ 288 | public void checkAlertText(String text) throws TestCaseFailed { 289 | if (!getAlertText().equals(text)) 290 | throw new TestCaseFailed("Text on alert pop up not matched"); 291 | } 292 | 293 | /** 294 | * Method to verify if the particular option is Selected from Dropdown 295 | * 296 | * @param accessType : String : Locator type (id, name, class, xpath, css) 297 | * @param by : String : Select element from dropdown by text or value 298 | * @param option : String : Element to select from dropdown 299 | * @param accessName : String : Locator value 300 | * @param shouldBeSelected : Boolean : test case [true or false] 301 | * @throws TestCaseFailed 302 | */ 303 | public void isOptionFromDropdownSelected(String accessType, String by, String option, String accessName, 304 | boolean shouldBeSelected) throws TestCaseFailed { 305 | Select selectList = null; 306 | WebElement dropdown = getDriverWait().waitShort() 307 | .until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 308 | selectList = new Select(dropdown); 309 | 310 | String actualValue = ""; 311 | if (by.equals("text")) 312 | actualValue = selectList.getFirstSelectedOption().getText(); 313 | else 314 | actualValue = selectList.getFirstSelectedOption().getAttribute("value"); 315 | 316 | if ((!actualValue.equals(option)) && (shouldBeSelected)) 317 | throw new TestCaseFailed("Option Not Selected From Dropwdown"); 318 | else if ((actualValue.equals(option)) && (!shouldBeSelected)) 319 | throw new TestCaseFailed("Option Selected From Dropwdown"); 320 | } 321 | } 322 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/BaseTest.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | public interface BaseTest { 4 | MiscMethods miscmethodObj = new MiscMethods(); 5 | NavigateMethods navigationObj = new NavigateMethods(); 6 | AssertionMethods assertionObj = new AssertionMethods(); 7 | ClickElementsMethods clickObj = new ClickElementsMethods(); 8 | ConfigurationMethods configObj = new ConfigurationMethods(); 9 | InputMethods inputObj = new InputMethods(); 10 | ProgressMethods progressObj = new ProgressMethods(); 11 | JavascriptHandlingMethods javascriptObj = new JavascriptHandlingMethods(); 12 | ScreenShotMethods screenshotObj = new ScreenShotMethods(); 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/ClickElementsMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import org.openqa.selenium.JavascriptExecutor; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.interactions.Actions; 7 | import org.openqa.selenium.support.ui.ExpectedConditions; 8 | 9 | public class ClickElementsMethods extends AbstractPage implements BaseTest { 10 | private final SelectElementByType selectElementByType = new SelectElementByType(); 11 | // SelectElementByType eleType= new SelectElementByType(); 12 | private WebElement element = null; 13 | 14 | /** 15 | * Method to click on an element 16 | * 17 | * @param accessType : String : Locator type (id, name, class, xpath, css) 18 | * @param accessName : String : Locator value 19 | */ 20 | public void click(String accessType, String accessName) { 21 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 22 | element.click(); 23 | } 24 | 25 | /** 26 | * Method to forcefully click on an element 27 | * 28 | * @param accessType : String : Locator type (id, name, class, xpath, css) 29 | * @param accessName : String : Locator value 30 | */ 31 | public void clickForcefully(String accessType, String accessName) { 32 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 33 | JavascriptExecutor executor = (JavascriptExecutor) getDriver(); 34 | executor.executeScript("arguments[0].click();", element); 35 | } 36 | 37 | /** 38 | * Method to Double click on an element 39 | * 40 | * @param accessType : String : Locator type (id, name, class, xpath, css) 41 | */ 42 | public void doubleClick(String accessType, String accessValue) { 43 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessValue))); 44 | 45 | Actions action = new Actions(getDriver()); 46 | action.moveToElement(element).doubleClick().perform(); 47 | } 48 | } -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/ConfigurationMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import org.openqa.selenium.Capabilities; 5 | import org.openqa.selenium.remote.RemoteWebDriver; 6 | 7 | import java.text.DateFormat; 8 | import java.text.SimpleDateFormat; 9 | import java.util.Calendar; 10 | 11 | public class ConfigurationMethods extends AbstractPage { 12 | 13 | 14 | /** 15 | * Method to print desktop configuration 16 | */ 17 | public void printDesktopConfiguration() { 18 | DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss"); 19 | Calendar cal = Calendar.getInstance(); 20 | 21 | System.out.println("Following are machine configurations : \n"); 22 | System.out.println("Date (MM/DD/YYYY) and Time (HH:MM:SS) : " + dateFormat.format(cal.getTime())); 23 | 24 | Capabilities cap = (Capabilities) ((RemoteWebDriver) getDriver()).getCapabilities(); 25 | System.out.println("Browser : " + cap.getBrowserName()); 26 | System.out.println("Platform : " + cap.getPlatform()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/Constants.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | public class Constants { 4 | 5 | public static final long timeoutLong = 30; 6 | 7 | public static final long pollingLong = 200; 8 | 9 | public static final long timeoutShort = 10; 10 | 11 | public static final long pollingShort = 100; 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/DriverManager.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import io.appium.java_client.android.AndroidDriver; 4 | import io.appium.java_client.ios.IOSDriver; 5 | import io.github.bonigarcia.wdm.WebDriverManager; 6 | 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | import org.openqa.selenium.chrome.ChromeOptions; 10 | import org.openqa.selenium.edge.EdgeDriver; 11 | import org.openqa.selenium.firefox.FirefoxDriver; 12 | import org.openqa.selenium.firefox.FirefoxOptions; 13 | import org.openqa.selenium.remote.DesiredCapabilities; 14 | import org.openqa.selenium.remote.RemoteWebDriver; 15 | import org.openqa.selenium.safari.SafariDriver; 16 | 17 | import java.io.File; 18 | import java.io.FileInputStream; 19 | import java.io.InputStream; 20 | import java.net.MalformedURLException; 21 | import java.net.URL; 22 | import java.util.Enumeration; 23 | import java.util.Properties; 24 | 25 | public class DriverManager { 26 | private static final ThreadLocal driverThreadLocal = new ThreadLocal<>(); 27 | private static WebDriver driver; 28 | 29 | private static final Thread CLOSE_THREAD = new Thread() { 30 | @Override 31 | public void run() { 32 | driver.quit(); 33 | } 34 | }; 35 | 36 | /** 37 | * By default to web driver will be firefox 38 | *

39 | * Override it by passing -Dbrowser=Chrome to the command line arguments 40 | * 41 | * @return webdriver 42 | */ 43 | private static WebDriver chooseDriver() { 44 | String preferredDriver = System.getProperty("browser", "Firefox"); 45 | boolean headless = System.getProperty("headless", "false").equals("true"); 46 | 47 | switch (preferredDriver.toLowerCase()) { 48 | case "safari": 49 | return new SafariDriver(); 50 | case "edge": 51 | return new EdgeDriver(); 52 | case "chrome": 53 | final ChromeOptions chromeOptions = new ChromeOptions(); 54 | 55 | if (headless) { 56 | chromeOptions.addArguments("--headless"); 57 | } 58 | 59 | chromeOptions.addArguments("window-size=1920,1080"); 60 | chromeOptions.addArguments("-incognito"); 61 | chromeOptions.addArguments("start-maximized"); 62 | chromeOptions.addArguments("disable-infobars"); 63 | chromeOptions.addArguments("--disable-extensions"); 64 | chromeOptions.addArguments("--disable-gpu"); 65 | chromeOptions.addArguments("--disable-dev-shm-usage"); 66 | chromeOptions.addArguments("--no-sandbox"); 67 | 68 | return new ChromeDriver(chromeOptions); 69 | default: 70 | final FirefoxOptions ffOptions = new FirefoxOptions(); 71 | 72 | if (headless) { 73 | ffOptions.setHeadless(true); 74 | } 75 | return new FirefoxDriver(ffOptions); 76 | } 77 | } 78 | 79 | public static DesiredCapabilities getCapability(InputStream input) { 80 | final Properties prop = new Properties(); 81 | DesiredCapabilities capability = new DesiredCapabilities(); 82 | try { 83 | prop.load(input); 84 | if (prop.containsKey("app")) { 85 | String appName = prop.getProperty("app"); 86 | if (!appName.contains("sauce-storage")) { 87 | String appPath = System.getProperty("user.dir") + "/src/main/java/appUnderTest/" + appName; 88 | prop.setProperty("app", appPath); 89 | } 90 | } 91 | 92 | // set capabilities 93 | Enumeration enuKeys = prop.keys(); 94 | while (enuKeys.hasMoreElements()) { 95 | String key = (String) enuKeys.nextElement(); 96 | String value = prop.getProperty(key); 97 | capability.setCapability(key, value); 98 | } 99 | input.close(); 100 | } catch (Exception e) { 101 | e.printStackTrace(); 102 | System.exit(0); 103 | } 104 | return capability; 105 | } 106 | 107 | /* 108 | * Returns saucelab remote driver instance by reading saucelab configuration 109 | * from platformConfigs/saucelab.properties 110 | * 111 | * @param DesiredCapabilities create capabilities by reading browser config. 112 | * 113 | * @return RemoteWebDriver 114 | */ 115 | private static WebDriver saucelabDriver() { 116 | final DesiredCapabilities capability = null; 117 | final URL remoteDriverURL; 118 | RemoteWebDriver remoteDriver = null; 119 | final Properties prop = new Properties(); 120 | 121 | try { 122 | InputStream input = new FileInputStream( 123 | System.getProperty("user.dir") + "/src/main/java/browserConfigs/" + System.getProperty("config", "") + ".properties"); 124 | 125 | prop.load(input); 126 | } catch (Exception ex) { 127 | ex.printStackTrace(); 128 | System.exit(0); 129 | } 130 | 131 | // set app path for app testing 132 | if (prop.containsKey("app")) { 133 | String appName = prop.getProperty("app").split(":")[1]; 134 | String appPath = System.getProperty("user.dir") + "/src/main/java/appUnderTest/" + appName; 135 | 136 | File appFile = new File(appPath); 137 | if (appFile.exists()) { 138 | // prop.setProperty("app", appPath); 139 | SauceLabsFileManager.uploadAppToSauceStorage(appName, appPath, prop); 140 | } else { 141 | System.out.println("Exception : No app with name '" + appName + "' found in appUnderTest directory"); 142 | System.exit(0); 143 | } 144 | } 145 | 146 | try { 147 | InputStream input = new FileInputStream(System.getProperty("user.dir") + "/src/main/java/platformConfigs/saucelab.properties"); 148 | prop.load(input); 149 | 150 | String url = prop.getProperty("protocol") + "://" + prop.getProperty("username") + ":" 151 | + prop.getProperty("access_key") + prop.getProperty("url"); 152 | 153 | input.close(); 154 | prop.clear(); 155 | remoteDriverURL = new URL(url); 156 | remoteDriver = new RemoteWebDriver(remoteDriverURL, capability); 157 | } catch (Exception e) { 158 | e.printStackTrace(); 159 | System.exit(0); 160 | } 161 | return remoteDriver; 162 | } 163 | 164 | /* 165 | * Returns browserStack remote driver instance by reading browserStack 166 | * configuration from platformConfigs/browserstack.properties 167 | * 168 | * @param DesiredCapabilities create capabilities by reading browser config. 169 | * 170 | * @return RemoteWebDriver 171 | */ 172 | private static WebDriver browserStackDriver() { 173 | DesiredCapabilities capability = null; 174 | final Properties prop = new Properties(); 175 | URL remoteDriverURL = null; 176 | try { 177 | InputStream input = new FileInputStream( 178 | System.getProperty("user.dir") + "/src/main/java/platformConfigs/browserstack.properties"); 179 | prop.load(input); 180 | 181 | String url = prop.getProperty("protocol") + "://" + prop.getProperty("username") + ":" 182 | + prop.getProperty("access_key") + prop.getProperty("url"); 183 | 184 | input.close(); 185 | prop.clear(); 186 | remoteDriverURL = new URL(url); 187 | } catch (Exception e) { 188 | e.printStackTrace(); 189 | } 190 | return new RemoteWebDriver(remoteDriverURL, capability); 191 | } 192 | 193 | private static WebDriver androidDriver(DesiredCapabilities capabilities) { 194 | String port = "4723"; 195 | try { 196 | driver = new AndroidDriver<>(new URL("http://127.0.0.1:" + port + "/wd/hub"), capabilities); 197 | } catch (MalformedURLException e) { 198 | e.printStackTrace(); 199 | } 200 | return driver; 201 | } 202 | 203 | private static WebDriver iosDriver(DesiredCapabilities capabilities) { 204 | String port = "4723"; 205 | try { 206 | driver = new IOSDriver<>(new URL("http://127.0.0.1:" + port + "/wd/hub"), capabilities); 207 | } catch (MalformedURLException e) { 208 | e.printStackTrace(); 209 | } 210 | return driver; 211 | } 212 | 213 | public WebDriver getDriver() { 214 | if (driverThreadLocal.get() != null) { 215 | return driverThreadLocal.get(); 216 | } else { 217 | return getDefaultDriver(); 218 | } 219 | } 220 | 221 | public WebDriver getDefaultDriver() { 222 | DesiredCapabilities capability = null; 223 | if (driverThreadLocal.get() != null) { 224 | return driverThreadLocal.get(); 225 | } 226 | WebDriverManager.chromedriver().setup(); 227 | 228 | String enviroment = "desktop"; 229 | String platform = ""; 230 | String config = System.getProperty("config", ""); 231 | 232 | if (!config.isEmpty()) { 233 | try { 234 | enviroment = config.split("_")[0].toLowerCase(); 235 | platform = config.split("_")[1].toLowerCase(); 236 | InputStream input = new FileInputStream( 237 | System.getProperty("user.dir") + "/src/main/java/browserConfigs/" + config + ".properties"); 238 | capability = getCapability(input); 239 | } catch (Exception e) { 240 | System.out.println( 241 | "\nException : File not present or Invalid config file name " + config + ".properties"); 242 | System.out.println("Config file format should be : enviroment_platform_device.properties"); 243 | System.out.println("\nE.g : local_android_nexus5.properties"); 244 | System.out.println("E.g : local_ios_iphone6.properties"); 245 | System.out.println("E.g : browserstack_android_nexus5.properties"); 246 | System.out.println("E.g : saucelab_windows7_chrome.properties"); 247 | System.exit(0); 248 | } 249 | } 250 | 251 | switch (enviroment) { 252 | case "local": 253 | if (platform.equals("android")) 254 | driver = androidDriver(capability); 255 | else if (platform.equals("ios")) 256 | driver = iosDriver(capability); 257 | else { 258 | System.out.println("unsupported platform"); 259 | System.exit(0); 260 | } 261 | break; 262 | case "browserstack": 263 | driver = browserStackDriver(); 264 | break; 265 | case "saucelab": 266 | driver = saucelabDriver(); 267 | break; 268 | case "desktop": 269 | driver = chooseDriver(); 270 | break; 271 | default: 272 | System.out.println("\nException : Invalid platform " + enviroment); 273 | System.exit(0); 274 | } 275 | driver.manage().window().maximize(); 276 | driverThreadLocal.set(driver); 277 | Runtime.getRuntime().addShutdownHook(CLOSE_THREAD); 278 | return getDriver(); 279 | } 280 | 281 | 282 | } 283 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/DriverWait.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import com.paulhammant.ngwebdriver.NgWebDriver; 4 | import info.seleniumcucumber.utils.expectedConditions.ClickabilityOfElement; 5 | import info.seleniumcucumber.utils.expectedConditions.ClickabilityOfElementByLocator; 6 | import info.seleniumcucumber.utils.expectedConditions.InvisibilityOfElement; 7 | import info.seleniumcucumber.utils.expectedConditions.InvisibilityOfElementByLocator; 8 | import info.seleniumcucumber.utils.expectedConditions.VisibilityOfElement; 9 | import info.seleniumcucumber.utils.expectedConditions.VisibilityOfElementByLocator; 10 | import org.openqa.selenium.By; 11 | import org.openqa.selenium.JavascriptExecutor; 12 | import org.openqa.selenium.ScriptTimeoutException; 13 | import org.openqa.selenium.StaleElementReferenceException; 14 | import org.openqa.selenium.WebDriver; 15 | import org.openqa.selenium.WebElement; 16 | import org.openqa.selenium.support.ui.ExpectedCondition; 17 | import org.openqa.selenium.support.ui.FluentWait; 18 | import org.openqa.selenium.support.ui.Wait; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | import java.time.Duration; 23 | import java.util.NoSuchElementException; 24 | 25 | public class DriverWait { 26 | 27 | private final Logger logger = LoggerFactory.getLogger(DriverWait.class); 28 | 29 | private final DriverManager driverManager; 30 | 31 | public DriverWait(DriverManager driverManager) { 32 | this.driverManager = driverManager; 33 | } 34 | 35 | public void waitForAngular() { 36 | waitUntilAngularReady(); 37 | } 38 | 39 | public void waitForElementToLoad(WebElement element) throws NoSuchFieldException { 40 | waitForAngular(); 41 | waitForElementVisible(element); 42 | waitForElementClickable(element); 43 | } 44 | 45 | public void waitForElementToLoad(By locator) throws NoSuchFieldException { 46 | waitForAngular(); 47 | waitForElementVisible(locator); 48 | waitForElementClickable(locator); 49 | } 50 | 51 | /** 52 | * Wait for Angular loads using Ng Driver 53 | */ 54 | private void ngDriverWait() { 55 | final NgWebDriver ngWebDriver = new NgWebDriver((JavascriptExecutor) driverManager.getDriver()); 56 | try { 57 | ngWebDriver.waitForAngularRequestsToFinish(); 58 | } catch (ScriptTimeoutException exception) { 59 | logger.info("Problems waiting for Angular to load with NgWeb Driver"); 60 | logger.debug("Problems waiting for Angular to load with NgWeb Driver"); 61 | } 62 | } 63 | 64 | /** 65 | * wait for element visible by element 66 | */ 67 | private void waitForElementVisible(WebElement element) { 68 | try { 69 | waitLong().until(new VisibilityOfElement(element)); 70 | } catch (Exception ignored) { 71 | } 72 | } 73 | 74 | /** 75 | * wait for element visible by locator 76 | */ 77 | private void waitForElementVisible(By locator) { 78 | try { 79 | waitLong().until(new VisibilityOfElementByLocator(locator)); 80 | } catch (Exception ignored) { 81 | } 82 | } 83 | 84 | /** 85 | * wait for element Invisible by locator 86 | */ 87 | private void waitForElementInVisible(By locator) { 88 | try { 89 | new InvisibilityOfElementByLocator(locator); 90 | } catch (Exception ignored) { 91 | } 92 | } 93 | 94 | /** 95 | * wait for element Invisible by locator 96 | */ 97 | private void waitForElementInVisible(WebElement element) { 98 | try { 99 | new InvisibilityOfElement(element); 100 | } catch (Exception ignored) { 101 | } 102 | } 103 | 104 | /** 105 | * wait for element clickable by element 106 | */ 107 | private void waitForElementClickable(WebElement element) throws NoSuchFieldException { 108 | try { 109 | new ClickabilityOfElement(element); 110 | } catch (Exception t) { 111 | throw new NoSuchFieldException("could not interact with the element " + element); 112 | } 113 | } 114 | 115 | /** 116 | * wait for element clickable by locator 117 | */ 118 | private void waitForElementClickable(By locator) throws NoSuchFieldException { 119 | try { 120 | new ClickabilityOfElementByLocator(locator); 121 | } catch (Exception t) { 122 | throw new NoSuchFieldException("could not interact with the element by locator " + locator); 123 | } 124 | } 125 | 126 | public Wait waitLong() { 127 | return new FluentWait<>(driverManager.getDriver()) 128 | .withTimeout(Duration.ofSeconds(Constants.timeoutLong)) 129 | .pollingEvery(Duration.ofMillis(Constants.pollingLong)) 130 | .ignoring(NoSuchElementException.class, StaleElementReferenceException.class); 131 | } 132 | 133 | public Wait waitShort() { 134 | return new FluentWait<>(driverManager.getDriver()) 135 | .withTimeout(Duration.ofSeconds(Constants.timeoutShort)) 136 | .pollingEvery(Duration.ofMillis(Constants.pollingShort)) 137 | .ignoring(NoSuchElementException.class, StaleElementReferenceException.class); 138 | } 139 | 140 | private void waitUntilAngularReady() { 141 | 142 | final Boolean angularUnDefined = (Boolean) ((JavascriptExecutor) driverManager.getDriver()).executeScript("return window.angular === undefined"); 143 | 144 | if (!angularUnDefined) { 145 | Boolean angularInjectorUnDefined = (Boolean) ((JavascriptExecutor) driverManager.getDriver()).executeScript("return angular.element(document).injector() === undefined"); 146 | if (!angularInjectorUnDefined) { 147 | waitForAngularLoad(); 148 | waitUntilJSReady(); 149 | waitForJQueryLoad(); 150 | ngDriverWait(); 151 | } 152 | } 153 | } 154 | 155 | private void waitForAngularLoad() { 156 | 157 | final String angularReadyScript = "return angular.element(document).injector().get('$http').pendingRequests.length === 0"; 158 | 159 | final ExpectedCondition angularLoad = driver -> Boolean.valueOf( 160 | ((JavascriptExecutor) driverManager.getDriver()).executeScript(angularReadyScript).toString()); 161 | 162 | boolean angularReady = Boolean 163 | .parseBoolean(((JavascriptExecutor) driverManager.getDriver()).executeScript(angularReadyScript).toString()); 164 | 165 | if (!angularReady) { 166 | waitLong().until(angularLoad); 167 | } 168 | } 169 | 170 | private void waitUntilJSReady() { 171 | final ExpectedCondition jsLoad = driver -> ((JavascriptExecutor) driverManager.getDriver()) 172 | .executeScript("return document.readyState") 173 | .toString() 174 | .equals("complete"); 175 | 176 | boolean jsReady = ((JavascriptExecutor) driverManager.getDriver()).executeScript("return document.readyState") 177 | .toString().equals("complete"); 178 | 179 | if (!jsReady) { 180 | waitLong().until(jsLoad); 181 | } 182 | } 183 | 184 | private void waitForJQueryLoad() { 185 | final ExpectedCondition jQueryLoad = driver -> ( 186 | (Long) ((JavascriptExecutor) driverManager.getDriver()).executeScript("return jQuery.active") == 0); 187 | 188 | boolean jqueryReady = (Boolean) ((JavascriptExecutor) driverManager.getDriver()).executeScript("return jQuery.active==0"); 189 | 190 | if (!jqueryReady) { 191 | waitLong().until(jQueryLoad); 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/ErrorHandlingMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import java.util.Arrays; 4 | 5 | public class ErrorHandlingMethods { 6 | // Method to check browser type 7 | public void validateParameters(String platform, String browserType, String appPath) { 8 | if (platform.equals("desktop")) { 9 | if (Arrays.asList("ff", "ie", "chrome", "safari", "opera").contains(browserType)) 10 | printErrorDesktop(); 11 | } else if (platform.equals("android")) 12 | printErrorAndroid(browserType, appPath); 13 | else if (platform.equals("iOS")) 14 | System.out.println("Not Implemented..."); 15 | else 16 | printInvalidPlatform(); 17 | } 18 | 19 | // print error for desktop 20 | private void printErrorDesktop() { 21 | System.out.println("\nInappropraite desktop browser : \"#{ENV['BROWSER']}\""); 22 | System.out.println("\nUsage : cucumber BROWSER=browser_name"); 23 | System.out.println("\nBrowser Supported :\n"); 24 | System.out.println("\n1.ie\n2.chrome\n3.ff\n4.safari\n5.opera"); 25 | System.exit(0); 26 | } 27 | 28 | // print error for android 29 | public void printErrorAndroid(String browserType, String appPath) { 30 | /* 31 | * if browser_type=='ff' and app_path==nil puts 32 | * "\nOops... not mentioned \"Browser\" or \"App path\"" 33 | * print_error_android_app print_error_android_web Process.exit(0) elsif 34 | * browser_type!='ff' and !%w(native chrome).include? browser_type puts 35 | * "\nOops... not supported browser" print_error_android_web 36 | * Process.exit(0) end end 37 | */ 38 | } 39 | 40 | // print error if invalid platform 41 | public void printInvalidPlatform() { 42 | System.out.println("\nOops... Invalid Platform"); 43 | System.out.println("\nSupported platform are \"android\" and \"iOS\"."); 44 | System.out.println("\nTo run on Desktop no need to mention platform."); 45 | System.exit(0); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/InputMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.ui.ExpectedConditions; 6 | import org.openqa.selenium.support.ui.Select; 7 | 8 | import java.util.List; 9 | 10 | public class InputMethods extends AbstractPage implements BaseTest { 11 | private final SelectElementByType selectElementByType = new SelectElementByType(); 12 | private WebElement dropdown = null; 13 | private Select selectList = null; 14 | 15 | /** 16 | * Method to enter text into text field 17 | * 18 | * @param accessType : String : Locator type (id, name, class, xpath, css) 19 | * @param text : String : Text value to enter in field 20 | * @param accessName : String : Locator value 21 | */ 22 | public void enterText(String accessType, String text, String accessName) { 23 | getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 24 | getDriver().findElement(selectElementByType.getelementbytype(accessType, accessName)).sendKeys(text); 25 | } 26 | 27 | /** 28 | * Method to clear text of text field 29 | * 30 | * @param accessType : String : Locator type (id, name, class, xpath, css) 31 | * @param accessName : String : Locator value 32 | */ 33 | public void clearText(String accessType, String accessName) { 34 | getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 35 | getDriver().findElement(selectElementByType.getelementbytype(accessType, accessName)).clear(); 36 | } 37 | 38 | /** 39 | * Method to select element from Dropdown by type 40 | * 41 | * @param select_list : Select : Select variable 42 | * @param bytype : String : Name of by type 43 | * @param option : String : Option to select 44 | */ 45 | public void selectelementfromdropdownbytype(Select select_list, String bytype, String option) { 46 | if (bytype.equals("selectByIndex")) { 47 | int index = Integer.parseInt(option); 48 | select_list.selectByIndex(index - 1); 49 | } else if (bytype.equals("value")) 50 | select_list.selectByValue(option); 51 | else if (bytype.equals("text")) 52 | select_list.selectByVisibleText(option); 53 | } 54 | 55 | /** 56 | * Method to select option from dropdown list 57 | * 58 | * @param accessType : String : Locator type (id, name, class, xpath, css) 59 | * @param option : String : Option to select 60 | * @param accessName : String : Locator value 61 | */ 62 | public void selectOptionFromDropdown(String accessType, String optionBy, String option, String accessName) { 63 | dropdown = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 64 | selectList = new Select(dropdown); 65 | 66 | if (optionBy.equals("selectByIndex")) 67 | selectList.selectByIndex(Integer.parseInt(option) - 1); 68 | else if (optionBy.equals("value")) 69 | selectList.selectByValue(option); 70 | else if (optionBy.equals("text")) 71 | selectList.selectByVisibleText(option); 72 | } 73 | 74 | // method to select all option from dropdwon list 75 | // public void select_all_option_from_multiselect_dropdown(String 76 | // access_type, String access_name) 77 | // { 78 | // dropdown = driver.findElement(selectElementByType.getelementbytype(access_type, 79 | // access_name)); 80 | // selectList = new Select(dropdown); 81 | // 82 | // //Select all method not present in JAVA 83 | // } 84 | 85 | /** 86 | * Method to unselect all option from dropdwon list 87 | * 88 | * @param accessType : String : Locator type (id, name, class, xpath, css) 89 | * @param accessName : String : Locator value 90 | */ 91 | public void unselectAllOptionFromMultiselectDropdown(String accessType, String accessName) { 92 | dropdown = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 93 | selectList = new Select(dropdown); 94 | selectList.deselectAll(); 95 | } 96 | 97 | /** 98 | * Method to unselect option from dropdwon list 99 | * 100 | * @param accessType : String : Locator type (id, name, class, xpath, css) 101 | * @param accessName : String : Locator value 102 | */ 103 | public void deselectOptionFromDropdown(String accessType, String optionBy, String option, String accessName) { 104 | dropdown = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 105 | selectList = new Select(dropdown); 106 | 107 | if (optionBy.equals("selectByIndex")) 108 | selectList.deselectByIndex(Integer.parseInt(option) - 1); 109 | else if (optionBy.equals("value")) 110 | selectList.deselectByValue(option); 111 | else if (optionBy.equals("text")) 112 | selectList.deselectByVisibleText(option); 113 | } 114 | 115 | /** 116 | * Method to check check-box 117 | * 118 | * @param accessType : String : Locator type (id, name, class, xpath, css) 119 | * @param accessName : String : Locator value 120 | */ 121 | public void checkCheckbox(String accessType, String accessName) { 122 | WebElement checkbox = getDriverWait().waitShort() 123 | .until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 124 | if (!checkbox.isSelected()) 125 | checkbox.click(); 126 | } 127 | 128 | /** 129 | * Method to uncheck check-box 130 | * 131 | * @param accessType : String : Locator type (id, name, class, xpath, css) 132 | * @param accessName : String : Locator value 133 | */ 134 | public void uncheckCheckbox(String accessType, String accessName) { 135 | WebElement checkbox = getDriverWait().waitShort() 136 | .until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 137 | if (checkbox.isSelected()) 138 | checkbox.click(); 139 | } 140 | 141 | /** 142 | * Method to toggle check-box status 143 | * 144 | * @param accessType : String : Locator type (id, name, class, xpath, css) 145 | * @param accessName : String : Locator value 146 | */ 147 | public void toggleCheckbox(String accessType, String accessName) { 148 | getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))).click(); 149 | } 150 | 151 | /** 152 | * Method to select radio button 153 | * 154 | * @param accessType : String : Locator type (id, name, class, xpath, css) 155 | * @param accessName : String : Locator value 156 | */ 157 | public void selectRadioButton(String accessType, String accessName) { 158 | WebElement radioButton = getDriverWait().waitShort() 159 | .until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 160 | if (!radioButton.isSelected()) 161 | radioButton.click(); 162 | } 163 | 164 | /** 165 | * Method to select option from radio button group 166 | * 167 | * @param accessType : String : Locator type (id, name, class, xpath, css) 168 | * @param by : String : Name of by type 169 | * @param option : String : Option to select 170 | * @param accessName : String : Locator value 171 | */ 172 | public void selectOptionFromRadioButtonGroup(String accessType, String option, String by, String accessName) { 173 | List radioButtonGroup = getDriver().findElements(selectElementByType.getelementbytype(accessType, accessName)); 174 | for (WebElement rb : radioButtonGroup) { 175 | if (by.equals("value")) { 176 | if (rb.getAttribute("value").equals(option) && !rb.isSelected()) 177 | rb.click(); 178 | } else if (by.equals("text")) { 179 | if (rb.getText().equals(option) && !rb.isSelected()) 180 | rb.click(); 181 | } 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/JavascriptHandlingMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | 5 | public class JavascriptHandlingMethods extends AbstractPage { 6 | /** 7 | * Method to handle alert 8 | * 9 | * @param decision : String : Accept or dismiss alert 10 | */ 11 | public void handleAlert(String decision) { 12 | if (decision.equals("accept")) 13 | getDriver().switchTo().alert().accept(); 14 | else 15 | getDriver().switchTo().alert().dismiss(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/MiscMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import java.util.Arrays; 4 | 5 | public class MiscMethods { 6 | public boolean valid_locator_type(String type) { 7 | return Arrays.asList("id", "class", "css", "name", "xpath").contains(type); 8 | } 9 | 10 | /** 11 | * Method to verify locator type 12 | * 13 | * @param type : String : Locator type (id, name, class, xpath, css) 14 | */ 15 | public void validateLocator(String type) throws Exception { 16 | if (!valid_locator_type(type)) 17 | throw new Exception("Invalid locator type - " + type); 18 | } 19 | 20 | // method to validate dropdown selector 21 | public boolean valid_option_by(String option_by) { 22 | return Arrays.asList("text", "value", "index").contains(option_by); 23 | } 24 | 25 | /** 26 | * Method to verify dropdown selector (text, value or index) 27 | * 28 | * @param optionBy : String : Locator type (text, value, index) 29 | */ 30 | public void validateOptionBy(String optionBy) throws Exception { 31 | if (!valid_option_by(optionBy)) 32 | throw new Exception("Invalid option by - " + optionBy); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/NavigateMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import org.openqa.selenium.Dimension; 5 | import org.openqa.selenium.JavascriptExecutor; 6 | import org.openqa.selenium.Keys; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.interactions.Actions; 9 | import org.openqa.selenium.support.ui.ExpectedConditions; 10 | 11 | public class NavigateMethods extends AbstractPage implements BaseTest { 12 | private final SelectElementByType selectElementByType = new SelectElementByType(); 13 | private WebElement element = null; 14 | private String old_win = null; 15 | private String lastWinHandle; 16 | 17 | /** 18 | * Method to open link 19 | * 20 | * @param url : String : URL for navigation 21 | */ 22 | public void navigateTo(String url) { 23 | getDriver().get(url); 24 | } 25 | 26 | /** 27 | * Method to navigate back & forward 28 | * 29 | * @param direction : String : Navigate to forward or backward 30 | */ 31 | public void navigate(String direction) { 32 | if (direction.equals("back")) 33 | getDriver().navigate().back(); 34 | else 35 | getDriver().navigate().forward(); 36 | } 37 | 38 | /** 39 | * Method to return key by OS wise 40 | * 41 | * @return Keys : Return control or command key as per OS 42 | */ 43 | public Keys getKey() { 44 | String os = System.getProperty("os.name").toLowerCase(); 45 | if (os.contains("win")) 46 | return Keys.CONTROL; 47 | else if (os.contains("nux") || os.contains("nix")) 48 | return Keys.CONTROL; 49 | else if (os.contains("mac")) 50 | return Keys.COMMAND; 51 | else 52 | return null; 53 | } 54 | 55 | /** 56 | * Method to zoom in/out page 57 | * 58 | * @param inOut : String : Zoom in or out 59 | */ 60 | public void zoomInOut(String inOut) { 61 | WebElement Sel = getDriver().findElement(selectElementByType.getelementbytype("tagName", "html")); 62 | switch (inOut) { 63 | case "ADD": 64 | Sel.sendKeys(Keys.chord(getKey(), Keys.ADD)); 65 | break; 66 | case "SUBTRACT": 67 | Sel.sendKeys(Keys.chord(getKey(), Keys.SUBTRACT)); 68 | break; 69 | case "reset": 70 | Sel.sendKeys(Keys.chord(getKey(), Keys.NUMPAD0)); 71 | break; 72 | } 73 | } 74 | 75 | /** 76 | * Method to zoom in/out web page until web element displays 77 | * 78 | * @param accessType : String : Locator type (id, name, class, xpath, css) 79 | * @param inOut : String : Zoom in or out 80 | * @param accessName : String : Locator value 81 | */ 82 | public void zoomInOutTillElementDisplay(String accessType, String inOut, String accessName) { 83 | Actions action = new Actions(getDriver()); 84 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 85 | while (true) { 86 | if (element.isDisplayed()) 87 | break; 88 | else 89 | action.keyDown(getKey()).sendKeys(inOut).keyUp(getKey()).perform(); 90 | } 91 | } 92 | 93 | /** 94 | * Method to resize browser 95 | * 96 | * @param width : int : Width for browser resize 97 | * @param height : int : Height for browser resize 98 | */ 99 | public void resizeBrowser(int width, int height) { 100 | getDriver().manage().window().setSize(new Dimension(width, height)); 101 | } 102 | 103 | /** 104 | * Method to maximize browser 105 | */ 106 | public void maximizeBrowser() { 107 | getDriver().manage().window().maximize(); 108 | } 109 | 110 | /** 111 | * Method to hover on element 112 | * 113 | * @param accessType : String : Locator type (id, name, class, xpath, css) 114 | * @param accessName : String : Locator value 115 | */ 116 | public void hoverOverElement(String accessType, String accessName) { 117 | Actions action = new Actions(getDriver()); 118 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 119 | action.moveToElement(element).perform(); 120 | } 121 | 122 | /** 123 | * Method to scroll page to particular element 124 | * 125 | * @param accessType : String : Locator type (id, name, class, xpath, css) 126 | * @param accessName : String : Locator value 127 | */ 128 | public void scrollToElement(String accessType, String accessName) { 129 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 130 | JavascriptExecutor executor = (JavascriptExecutor) getDriver(); 131 | executor.executeScript("arguments[0].scrollIntoView();", element); 132 | } 133 | 134 | /** 135 | * Method to scroll page to top or end 136 | * 137 | * @param to : String : Scroll page to Top or End 138 | */ 139 | public void scrollPage(String to) throws Exception { 140 | JavascriptExecutor executor = (JavascriptExecutor) getDriver(); 141 | if (to.equals("end")) 142 | executor.executeScript( 143 | "window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));"); 144 | else if (to.equals("top")) 145 | executor.executeScript( 146 | "window.scrollTo(Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight),0);"); 147 | else 148 | throw new Exception("Exception : Invalid Direction (only scroll \"top\" or \"end\")"); 149 | } 150 | 151 | /** 152 | * Method to switch to new window 153 | */ 154 | public void switchToNewWindow() { 155 | old_win = getDriver().getWindowHandle(); 156 | for (String winHandle : getDriver().getWindowHandles()) 157 | lastWinHandle = winHandle; 158 | getDriver().switchTo().window(lastWinHandle); 159 | } 160 | 161 | /** 162 | * Method to switch to old window 163 | */ 164 | public void switchToOldWindow() { 165 | getDriver().switchTo().window(old_win); 166 | } 167 | 168 | /** 169 | * Method to switch to window by title 170 | * 171 | * @param windowTitle : String : Name of window title to switch 172 | */ 173 | public void switchToWindowByTitle(String windowTitle) throws Exception { 174 | // System.out.println("++"+windowTitle+"++"); 175 | old_win = getDriver().getWindowHandle(); 176 | boolean winFound = false; 177 | for (String winHandle : getDriver().getWindowHandles()) { 178 | String str = getDriver().switchTo().window(winHandle).getTitle(); 179 | // System.out.println("**"+str+"**"); 180 | if (str.equals(windowTitle)) { 181 | winFound = true; 182 | break; 183 | } 184 | } 185 | if (!winFound) 186 | throw new Exception("Window having title " + windowTitle + " not found"); 187 | } 188 | 189 | /** 190 | * Method to close new window 191 | */ 192 | public void closeNewWindow() { 193 | getDriver().close(); 194 | } 195 | 196 | /** 197 | * Method to switch frame using web element frame 198 | * 199 | * @param accessType : String : Locator type (index, id, name, class, xpath, css) 200 | * @param accessName : String : Locator value 201 | */ 202 | public void switchFrame(String accessType, String accessName) { 203 | if (accessType.equalsIgnoreCase("index")) 204 | getDriver().switchTo().frame(accessName); 205 | else { 206 | element = getDriverWait().waitShort().until(ExpectedConditions.presenceOfElementLocated(selectElementByType.getelementbytype(accessType, accessName))); 207 | getDriver().switchTo().frame(element); 208 | } 209 | } 210 | 211 | /** 212 | * method to switch to default content 213 | */ 214 | public void switchToDefaultContent() { 215 | getDriver().switchTo().defaultContent(); 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/ProgressMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.support.ui.ExpectedConditions; 6 | import org.openqa.selenium.support.ui.WebDriverWait; 7 | 8 | public class ProgressMethods extends AbstractPage implements BaseTest { 9 | 10 | private final SelectElementByType selectElementByType = new SelectElementByType(); 11 | 12 | /** 13 | * Method to Explicitly wait for element to be displayed 14 | * 15 | * @param accessType : String : Locator type (id, name, class, xpath, css) 16 | * @param accessName : String : Locator value 17 | * @param duration : String : Time to wait for element to be displayed 18 | */ 19 | public void waitForElementToDisplay(String accessType, String accessName, String duration) { 20 | By byEle = selectElementByType.getelementbytype(accessType, accessName); 21 | WebDriverWait wait = (new WebDriverWait(getDriver(), Integer.parseInt(duration) * 1000L)); 22 | wait.until(ExpectedConditions.visibilityOfElementLocated(byEle)); 23 | } 24 | 25 | /** 26 | * Method to Explicitly wait for element to be enabled=click 27 | * 28 | * @param accessType : String : Locator type (id, name, class, xpath, css) 29 | * @param accessName : String : Locator value 30 | * @param duration : String : Time to wait for element to be clickable 31 | */ 32 | public void waitForElementToClick(String accessType, String accessName, String duration) { 33 | By byEle = selectElementByType.getelementbytype(accessType, accessName); 34 | WebDriverWait wait = (new WebDriverWait(getDriver(), Integer.parseInt(duration) * 1000L)); 35 | wait.until(ExpectedConditions.elementToBeClickable(byEle)); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/SauceLabsFileManager.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.BufferedOutputStream; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.net.HttpURLConnection; 10 | import java.net.URL; 11 | import java.net.URLConnection; 12 | import java.util.Base64; 13 | import java.util.Properties; 14 | 15 | public class SauceLabsFileManager { 16 | 17 | static void uploadAppToSauceStorage(String appName, String appPath, Properties prop) { 18 | System.out.println("Uploading App " + appName + " to sauce storage"); 19 | InputStream input; 20 | String username = prop.getProperty("username"); 21 | String access_key = prop.getProperty("access_key"); 22 | 23 | String uploadURL = "https://saucelabs.com/rest/v1/storage/" + username + "/" + appName + "?overwrite=true"; 24 | String encoding = Base64.getEncoder().encodeToString((username + ":" + access_key).getBytes()); 25 | 26 | URLConnection urlconnection = null; 27 | try { 28 | File file = new File(appPath); 29 | URL url = new URL(uploadURL); 30 | urlconnection = url.openConnection(); 31 | urlconnection.setDoOutput(true); 32 | urlconnection.setDoInput(true); 33 | 34 | if (urlconnection instanceof HttpURLConnection) { 35 | ((HttpURLConnection) urlconnection).setRequestMethod("POST"); 36 | urlconnection.setRequestProperty("Content-type", "text/plain"); 37 | urlconnection.setRequestProperty("Authorization", "Basic " + encoding); 38 | urlconnection.connect(); 39 | } 40 | 41 | BufferedOutputStream bos = new BufferedOutputStream(urlconnection.getOutputStream()); 42 | BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); 43 | int i; 44 | // read byte by byte until end of stream 45 | while ((i = bis.read()) > 0) { 46 | bos.write(i); 47 | } 48 | bis.close(); 49 | bos.close(); 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | } 53 | try { 54 | 55 | assert urlconnection != null; 56 | int responseCode = ((HttpURLConnection) urlconnection).getResponseCode(); 57 | if ((responseCode >= 200) && (responseCode <= 202)) { 58 | System.out.println("App uploaded successfully"); 59 | } else { 60 | System.out.println("App upload failed"); 61 | } 62 | System.out.println("responseCode : " + responseCode); 63 | 64 | ((HttpURLConnection) urlconnection).disconnect(); 65 | 66 | } catch (IOException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/ScreenShotMethods.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import info.seleniumcucumber.pages.AbstractPage; 4 | import org.apache.commons.io.FileUtils; 5 | import org.openqa.selenium.OutputType; 6 | import org.openqa.selenium.TakesScreenshot; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.text.DateFormat; 11 | import java.text.SimpleDateFormat; 12 | import java.util.Calendar; 13 | import java.util.Locale; 14 | 15 | public class ScreenShotMethods extends AbstractPage { 16 | /** 17 | * Method to take screen shot and save in ./screenShots folder 18 | */ 19 | public void takeScreenShot() throws IOException { 20 | File scrFile = ((TakesScreenshot) getDriver()).getScreenshotAs(OutputType.FILE); 21 | DateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy-z-HH:mm:ss", Locale.ENGLISH); 22 | Calendar cal = Calendar.getInstance(); 23 | //System.out.println(dateFormat.format(cal.getTime())); 24 | FileUtils.copyFile(scrFile, new File("screenShots/" + dateFormat.format(cal.getTime()) + ".png")); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/SelectElementByType.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import org.openqa.selenium.By; 4 | 5 | public class SelectElementByType { 6 | 7 | /** 8 | * Method to select element 'by' type 9 | * 10 | * @param type : String : 'By' type 11 | * @param access_name : String : Locator value 12 | * @return By 13 | */ 14 | public By getelementbytype(String type, String access_name) { 15 | switch (type) { 16 | case "id": 17 | return By.id(access_name); 18 | case "name": 19 | return By.name(access_name); 20 | case "class": 21 | return By.className(access_name); 22 | case "xpath": 23 | return By.xpath(access_name); 24 | case "css": 25 | return By.cssSelector(access_name); 26 | case "linkText": 27 | return By.linkText(access_name); 28 | case "partialLinkText": 29 | return By.partialLinkText(access_name); 30 | case "tagName": 31 | return By.tagName(access_name); 32 | default: 33 | return null; 34 | 35 | } 36 | /* 37 | * if(type.equals("id")) return By.id(access_name); else if 38 | * (type.equals("name")) return By.name(access_name); else if 39 | * (type.equals("class")) return By.className(access_name); else if 40 | * (type.equals("xpath")) return By.xpath(access_name); else if 41 | * (type.equals("css")) return By.cssSelector(access_name); else 42 | * if(type.equals("linkText")) return By.linkText(access_name); else 43 | * if(type.equals("partialLinkText")) return 44 | * By.partialLinkText(access_name); else if(type.equals("tagName")) 45 | * return By.tagName(access_name); else return null; 46 | */ 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/TestCaseFailed.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | public class TestCaseFailed extends Exception { 4 | /** 5 | * Added serializable varibale to remove warning 6 | */ 7 | private static final long serialVersionUID = 1L; 8 | String message = null; 9 | 10 | public TestCaseFailed() { 11 | super(); 12 | } 13 | 14 | public TestCaseFailed(String message) { 15 | super(message); 16 | this.message = message; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/Transformer.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import io.cucumber.cucumberexpressions.ParameterByTypeTransformer; 5 | import io.cucumber.datatable.TableCellByTypeTransformer; 6 | import io.cucumber.datatable.TableEntryByTypeTransformer; 7 | 8 | import java.lang.reflect.Type; 9 | import java.util.Map; 10 | 11 | class Transformer implements ParameterByTypeTransformer, TableEntryByTypeTransformer, 12 | TableCellByTypeTransformer { 13 | 14 | private final ObjectMapper objectMapper = new ObjectMapper(); 15 | 16 | public Object transform(String s, Type type) { 17 | return objectMapper.convertValue(s, objectMapper.constructType(type)); 18 | } 19 | 20 | public T transform(Map map, Class aClass, 21 | TableCellByTypeTransformer tableCellByTypeTransformer) { 22 | return objectMapper.convertValue(map, aClass); 23 | } 24 | 25 | public T transform(String s, Class aClass) { 26 | return objectMapper.convertValue(s, aClass); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/TypeRegistryConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils; 2 | 3 | import io.cucumber.core.api.TypeRegistry; 4 | import io.cucumber.core.api.TypeRegistryConfigurer; 5 | 6 | import java.util.Locale; 7 | 8 | import static java.util.Locale.ENGLISH; 9 | 10 | public class TypeRegistryConfiguration implements TypeRegistryConfigurer { 11 | 12 | public Locale locale() { 13 | return ENGLISH; 14 | } 15 | 16 | public void configureTypeRegistry(TypeRegistry typeRegistry) { 17 | Transformer transformer = new Transformer(); 18 | typeRegistry.setDefaultDataTableCellTransformer(transformer); 19 | typeRegistry.setDefaultDataTableEntryTransformer(transformer); 20 | typeRegistry.setDefaultParameterTransformer(transformer); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/expectedConditions/ClickabilityOfElement.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils.expectedConditions; 2 | 3 | import info.seleniumcucumber.utils.Constants; 4 | import org.openqa.selenium.ElementNotVisibleException; 5 | import org.openqa.selenium.NoSuchElementException; 6 | import org.openqa.selenium.StaleElementReferenceException; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.WebElement; 9 | import org.openqa.selenium.support.ui.ExpectedCondition; 10 | import org.openqa.selenium.support.ui.ExpectedConditions; 11 | import org.openqa.selenium.support.ui.FluentWait; 12 | import org.openqa.selenium.support.ui.Wait; 13 | 14 | import java.time.Duration; 15 | 16 | public class ClickabilityOfElement implements ExpectedCondition { 17 | 18 | private final WebElement element; 19 | 20 | public ClickabilityOfElement(WebElement element) { 21 | this.element = element; 22 | } 23 | 24 | @Override 25 | public WebElement apply(WebDriver webDriver) { 26 | 27 | final Wait wait = new FluentWait<>(webDriver) 28 | .withTimeout(Duration.ofSeconds(Constants.timeoutShort)) 29 | .pollingEvery(Duration.ofMillis(Constants.pollingShort)) 30 | .ignoring(java.util.NoSuchElementException.class, 31 | StaleElementReferenceException.class); 32 | try { 33 | return wait.until(ExpectedConditions.elementToBeClickable(element)); 34 | } catch (StaleElementReferenceException | NoSuchElementException | ElementNotVisibleException e) { 35 | return element; 36 | } catch (Throwable t) { 37 | throw new Error(t); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/expectedConditions/ClickabilityOfElementByLocator.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils.expectedConditions; 2 | 3 | import info.seleniumcucumber.utils.Constants; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.ElementNotVisibleException; 6 | import org.openqa.selenium.NoSuchElementException; 7 | import org.openqa.selenium.StaleElementReferenceException; 8 | import org.openqa.selenium.WebDriver; 9 | import org.openqa.selenium.WebElement; 10 | import org.openqa.selenium.support.ui.ExpectedCondition; 11 | import org.openqa.selenium.support.ui.ExpectedConditions; 12 | import org.openqa.selenium.support.ui.FluentWait; 13 | import org.openqa.selenium.support.ui.Wait; 14 | 15 | import java.time.Duration; 16 | 17 | public class ClickabilityOfElementByLocator implements ExpectedCondition { 18 | 19 | private final By locator; 20 | 21 | public ClickabilityOfElementByLocator(By locator) { 22 | this.locator = locator; 23 | } 24 | 25 | @Override 26 | public WebElement apply(WebDriver webDriver) { 27 | 28 | final Wait wait = new FluentWait<>(webDriver) 29 | .withTimeout(Duration.ofSeconds(Constants.timeoutShort)) 30 | .pollingEvery(Duration.ofMillis(Constants.pollingShort)) 31 | .ignoring(java.util.NoSuchElementException.class, 32 | StaleElementReferenceException.class); 33 | 34 | try { 35 | return wait.until(ExpectedConditions.elementToBeClickable(locator)); 36 | } catch (StaleElementReferenceException | NoSuchElementException | ElementNotVisibleException e) { 37 | return webDriver.findElement(locator); 38 | } catch (Throwable t) { 39 | throw new Error(t); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/expectedConditions/InvisibilityOfElement.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils.expectedConditions; 2 | 3 | import org.openqa.selenium.ElementNotVisibleException; 4 | import org.openqa.selenium.NoSuchElementException; 5 | import org.openqa.selenium.StaleElementReferenceException; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.support.ui.ExpectedCondition; 9 | 10 | public class InvisibilityOfElement implements ExpectedCondition { 11 | 12 | private final WebElement element; 13 | 14 | public InvisibilityOfElement(WebElement element) { 15 | this.element = element; 16 | } 17 | 18 | @Override 19 | public Boolean apply(WebDriver d) { 20 | try { 21 | return element.isDisplayed(); 22 | } catch (StaleElementReferenceException | NoSuchElementException | ElementNotVisibleException e) { 23 | return true; 24 | } catch (Throwable t) { 25 | throw new Error(t); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/expectedConditions/InvisibilityOfElementByLocator.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils.expectedConditions; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.ElementNotVisibleException; 5 | import org.openqa.selenium.NoSuchElementException; 6 | import org.openqa.selenium.StaleElementReferenceException; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.support.ui.ExpectedCondition; 9 | 10 | public class InvisibilityOfElementByLocator implements ExpectedCondition { 11 | 12 | private final By locator; 13 | 14 | public InvisibilityOfElementByLocator(By locator) { 15 | this.locator = locator; 16 | } 17 | 18 | @Override 19 | public Boolean apply(WebDriver d) { 20 | try { 21 | return d.findElement(locator).isDisplayed(); 22 | } catch (StaleElementReferenceException | NoSuchElementException | ElementNotVisibleException e) { 23 | return true; 24 | } catch (Throwable t) { 25 | throw new Error(t); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/expectedConditions/VisibilityOfElement.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils.expectedConditions; 2 | 3 | import org.openqa.selenium.ElementNotVisibleException; 4 | import org.openqa.selenium.NoSuchElementException; 5 | import org.openqa.selenium.StaleElementReferenceException; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.support.ui.ExpectedCondition; 9 | 10 | public class VisibilityOfElement implements ExpectedCondition { 11 | 12 | private final WebElement element; 13 | 14 | public VisibilityOfElement(WebElement element) { 15 | this.element = element; 16 | } 17 | 18 | @Override 19 | public Boolean apply(WebDriver d) { 20 | try { 21 | return element.isDisplayed(); 22 | } catch (StaleElementReferenceException | NoSuchElementException | ElementNotVisibleException e) { 23 | return false; 24 | } catch (Throwable t) { 25 | throw new Error(t); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/info/seleniumcucumber/utils/expectedConditions/VisibilityOfElementByLocator.java: -------------------------------------------------------------------------------- 1 | package info.seleniumcucumber.utils.expectedConditions; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.ElementNotVisibleException; 5 | import org.openqa.selenium.NoSuchElementException; 6 | import org.openqa.selenium.StaleElementReferenceException; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.support.ui.ExpectedCondition; 9 | 10 | public class VisibilityOfElementByLocator implements ExpectedCondition { 11 | 12 | private final By locator; 13 | 14 | public VisibilityOfElementByLocator(By locator) { 15 | this.locator = locator; 16 | } 17 | 18 | @Override 19 | public Boolean apply(WebDriver d) { 20 | try { 21 | return d.findElement(locator).isDisplayed(); 22 | } catch (StaleElementReferenceException | NoSuchElementException | ElementNotVisibleException e) { 23 | return false; 24 | } catch (Throwable t) { 25 | throw new Error(t); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/allure.properties: -------------------------------------------------------------------------------- 1 | # allure-reporter 2 | allure.results.directory=target/allure-results 3 | -------------------------------------------------------------------------------- /src/test/resources/configs/browserstack.properties: -------------------------------------------------------------------------------- 1 | username=your_username 2 | access_key=your_access_key 3 | url=@hub-cloud.browserstack.com/wd/hub 4 | protocol=http -------------------------------------------------------------------------------- /src/test/resources/configs/browserstack_android7_chrome.properties: -------------------------------------------------------------------------------- 1 | name=GooglePixelTest 2 | device=Google Pixel 3 | realMobile=true 4 | os_version=7.1 5 | browser=Android -------------------------------------------------------------------------------- /src/test/resources/configs/browserstack_win10_chrome.properties: -------------------------------------------------------------------------------- 1 | name=Windows10ChromeTest 2 | browser=Chrome 3 | browser_version=62.0 4 | os=Windows 5 | os_version=10 6 | resolution=1024x768 -------------------------------------------------------------------------------- /src/test/resources/configs/local_android_app_nexus5.properties: -------------------------------------------------------------------------------- 1 | deviceName=Nexus5 2 | platformName=android 3 | platformVersion=7.0 4 | app=AndroidCalculator.apk 5 | udid=192.168.49.101:5555 -------------------------------------------------------------------------------- /src/test/resources/configs/local_android_nexus5.properties: -------------------------------------------------------------------------------- 1 | deviceName=Nexus5 2 | platformName=android 3 | platformVersion=7.0 4 | browserName=Chrome 5 | udid=2454f24e -------------------------------------------------------------------------------- /src/test/resources/configs/saucelab.properties: -------------------------------------------------------------------------------- 1 | username=your_username 2 | access_key=your_access_key 3 | url=@ondemand.saucelabs.com:80/wd/hub 4 | protocol=http -------------------------------------------------------------------------------- /src/test/resources/configs/saucelab_android6_chrome.properties: -------------------------------------------------------------------------------- 1 | name=Android-Test 2 | appiumVersion=1.6.4 3 | deviceName=Android Emulator 4 | deviceOrientation=portrait 5 | browserName=Chrome 6 | platformVersion=6.0 7 | platformName=Android -------------------------------------------------------------------------------- /src/test/resources/configs/saucelab_android_app.properties: -------------------------------------------------------------------------------- 1 | name=CalcTest 2 | appiumVersion=1.6.4 3 | deviceName=Android GoogleAPI Emulator 4 | deviceOrientation=portrait 5 | platformVersion=7.0 6 | platformName=Android 7 | app=sauce-storage:AndroidCalculator.apk -------------------------------------------------------------------------------- /src/test/resources/configs/saucelab_android_app_nexus.properties: -------------------------------------------------------------------------------- 1 | name=Android-Test 2 | appiumVersion=1.6.4 3 | deviceName=Android Emulator 4 | deviceOrientation=portrait 5 | app=sauce-storage:AndroidCalculator.apk 6 | platformVersion=6.0 7 | platformName=Android -------------------------------------------------------------------------------- /src/test/resources/configs/saucelab_android_chrome.properties: -------------------------------------------------------------------------------- 1 | name=CalcTest 2 | appiumVersion=1.6.4 3 | deviceName=Android GoogleAPI Emulator 4 | deviceOrientation=portrait 5 | platformVersion=7.0 6 | platformName=Android 7 | browserName=chrome -------------------------------------------------------------------------------- /src/test/resources/configs/saucelab_windows_chrome52.properties: -------------------------------------------------------------------------------- 1 | name=Win10-Chrome49 2 | platform=Windows 10 3 | browserName=Chrome 4 | version=49.0 5 | -------------------------------------------------------------------------------- /src/test/resources/extent.properties: -------------------------------------------------------------------------------- 1 | # spark-reporter 2 | extent.reporter.spark.start=true 3 | extent.reporter.spark.config=src/test/resources/extent.xml 4 | extent.reporter.spark.out=target/reports/cucumber-spark-reports/spark-report.html 5 | # screenshot config 6 | screenshot.dir=target/ 7 | screenshot.rel.path=./ 8 | -------------------------------------------------------------------------------- /src/test/resources/extent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Test Framework 7 | 8 | 9 | 10 | UTF-8 11 | 12 | 13 | 14 | http 15 | 16 | 17 | Test Framework 18 | 19 | 20 | 21 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | dark 37 | 38 | 39 | MMM dd, yyyy HH:mm:ss 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/test/resources/features/my_first.feature: -------------------------------------------------------------------------------- 1 | Feature: Login 2 | As a user I should able to login into my app 3 | 4 | Scenario: I login with valid credential 5 | Given I navigate to "http://the-internet.herokuapp.com/login" 6 | Then I take screenshot 7 | And I enter "tomsmith" into input field having id "username" 8 | And I enter "SuperSecretPassword!" into input field having id "password" 9 | When I click on element having class "radius" 10 | Then I should get logged-in 11 | --------------------------------------------------------------------------------