├── .DS_Store ├── .github └── workflows │ └── maven-build.yml ├── .gitignore ├── LICENSE ├── README.md ├── orange-hrm ├── .gitignore ├── pom.xml └── src │ └── test │ ├── java │ └── com │ │ └── orangehrm │ │ ├── ApplitoolConfig.java │ │ ├── pages │ │ ├── mobile │ │ │ ├── HomePage.java │ │ │ └── LoginPage.java │ │ └── web │ │ │ ├── HomePage.java │ │ │ └── LoginPage.java │ │ └── step_def │ │ ├── api │ │ └── ApiSteps.java │ │ └── web │ │ └── LoginSteps.java │ └── resources │ ├── ApiTestNg.xml │ ├── WebTestNg.xml │ ├── extent.properties │ ├── feature │ ├── AddUser.feature │ ├── Api.feature │ └── Login.feature │ ├── help │ ├── Commands.txt │ ├── android_emulator_node_config.json │ ├── android_emulator_node_start.sh │ ├── android_mi2_node_config.json │ ├── android_mi2_node_start.sh │ └── chrome_node.sh │ └── properties │ ├── capabilities │ ├── .gitignore │ ├── BrowserCapabilities.properties │ └── iOSCapabilities.properties │ ├── framework │ ├── ApplitoolEyeConfig.properties │ └── FrameworkConfig.properties │ └── userDefined │ ├── Environment.properties │ └── QAEnvironmentConfig.properties └── test-automation-framework ├── .gitignore ├── pom.xml └── src └── main ├── java └── org │ └── iqa │ ├── suite │ └── commons │ │ ├── ApiUtils.java │ │ ├── AssertionFactory.java │ │ ├── CustomProperties.java │ │ ├── DBUtils.java │ │ ├── ExtentLogger.java │ │ ├── JavaUtils.java │ │ ├── PropertyHolder.java │ │ ├── SeleniumUtils.java │ │ ├── TestMetaData.java │ │ ├── applitool │ │ ├── ApplitoolEyesMobile.java │ │ ├── ApplitoolEyesWeb.java │ │ ├── ApplitoolsEyesUtils.java │ │ └── IConfigListner.java │ │ ├── database │ │ └── DBConnection.java │ │ ├── listeners │ │ └── TestNGMethodInvocationListener.java │ │ ├── mobile │ │ └── AdbOperations.java │ │ └── reporting │ │ └── ExtentReportTestFactory.java │ └── test │ ├── base │ ├── BasePageBrowser.java │ ├── BasePageMobile.java │ └── BaseTest.java │ ├── runner │ ├── ParallelTestRunner.java │ └── SequentialTestRunner.java │ ├── test_data │ ├── PersonData.java │ ├── RandomGenerator.java │ └── RuntimeTestDataHolder.java │ └── webdriver_factory │ ├── CapabilityFactory.java │ ├── WebDriverFactory.java │ └── WebDriverManager.java └── resources ├── ExtentConfig.xml ├── log4j.properties └── logback.xml /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/innovativeQALab/iqa-automation-framework/6590a6e4c00610d57cb201d02a1f20af1ac973bd/.DS_Store -------------------------------------------------------------------------------- /.github/workflows/maven-build.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see this: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: [ main ] 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Set up JDK 1.8 18 | uses: actions/setup-java@v1 19 | with: 20 | java-version: '1.8' 21 | server-id: ossrh 22 | server-username: MAVEN_USERNAME 23 | server-password: MAVEN_PASSWORD 24 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 25 | gpg-passphrase: MAVEN_GPG_PASSPHRASE 26 | - name: Build with Maven 27 | run: mvn -B package --file test-automation-framework/pom.xml 28 | - name: Deploy to Maven Central Repository 29 | run: mvn -B clean deploy -Pci-cd --file test-automation-framework/pom.xml 30 | env: 31 | MAVEN_USERNAME: ${{ secrets.SECRETS_OSSRH_USERNAME }} 32 | MAVEN_PASSWORD: ${{ secrets.SECRETS_OSSRH_TOKEN }} 33 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iqa-automation-framework 2 | 3 | > Evaluted from [cucumber-selenium-framework](https://github.com/zodgevaibhav/cucumber-selenium-framework) 4 | 5 | ### Supported Platforms 6 | 7 | 1. Selenium WebDriver based Web 8 | 2. Appium based Mobile (Android, iOS) 9 | 3. Windows Desktop 10 | 4. REST-Assired based API 11 | 12 | Automation Framework with BDD implementation support 13 | 14 | ### iQA Test Automation Framework Architecture 15 | 16 | ![image](https://user-images.githubusercontent.com/30923231/185048624-221c0edc-aaf8-4e82-b66d-0655f1368826.png) 17 | 18 | ### Features 19 | 1) With few Configurations and adding dependencies, you are ready to use this framework 20 | 2) Framework supports to test web application, Mobile application (Native, Web, Hybrid), Windows Native applications 21 | 3) BDD based Framework: 22 | 1) Tag based scenarios 23 | 2) Tag based execution 24 | 4) Parallel and Sequential execution support 25 | 5) Selenium Grid Support: It helps in running multiple tests across different browsers, operating systems, and machines in parallel 26 | 6) Database support- Do database Configuration and use it (MySQL, Oracle, etc.) 27 | 7) Test Data management facility at run time, global, static, Test script level 28 | 8) Logger and Reports Facility: 29 | 1) Test method level - Using Extent Report 30 | 2) Framework level - Using Log4j 31 | 9) Applitool Eye Support 32 | 33 | ### How To Start/Use 34 | 1) Create simple maven project in Eclipse 35 | 2) Get framework project from git and add following dependency and sure-fire plug in information in POM file 36 | Dependency: 37 | ```xml 38 | 39 | 40 | io.github.innovativeqalab 41 | test-automation-framework 42 | 1.0.0 43 | 44 | 45 | ``` 46 | 3) Create page object classes src/test/java folder 47 | 4) Create feature file/s in src/test/resources/feature folder and corresponding step definitions in src/test/java folder 48 | 5) Create testNG.xml file in src/test/resources folder 49 | 6) Create required configuration files in src/test/resources folder (as a properties file). 50 | Configuration file are categorised in to three part 51 | 1. framework - Which are set/written by user but used by Framework for execution. These can be mandatory properties. 52 | a. WebDriverConfig.properties - Configuration related to Selenium Grid, Platform, local execution, etc. 53 | b. ApplitoolEyeConfig.properties - Configuration related to Applitool (Applitool Enable/Disable, Batch Name) 54 | 2. capabilities - capabilities for the selenium grid/appium/sauceLab. 55 | 3. userDefined - General properties user want to use for any purpose ex. Global Test Data, Environment specific data, etc... 56 | 57 | ```Please refer sample project "orange-hrm" for more details``` 58 | 59 | ### Properties file configurations 60 | 1) WebDriverConfig.properties is the important file which decides whether to run the tests locally or on remote machines. It contains following important items 61 | - Driver mode : Remote or Local. Specify DRIVER=REMOTE for facilitating remote execution using remote driver. RemoteWebDriver capabilities must set in respective property files in src/test/resources/capabilities folder. DRIVER=BROWSER for execution on local machine. 62 | - Platform : WINDOWS or LINUX or IOS or ANDROID ... 63 | - Browser Name : Specify the browser you want to use 64 | - Browser Version : Specify the browser version. If not specified, it will consider the default one. 65 | - Driver Executables : Specify the complete path to driver exe. If Driver Mode is 'Remote', this property is not required. 66 | - Driver Property Name : Specify property name of the driver e.g for chrome driver, 'web driver.chrome.driver'. If Driver Mode is 'Remote', this property is not required. 67 | - Hub Url : This is required if the Driver Mode is Remote. Specify the selenium grid hub url or appium url as applicable 68 | 69 | 2) Environment.properties file will have name of the environment. Corresponding to each environment e.g QA, there needs be properties file in the user-defined folder like 'QAEnvironmentConfig.properties'. This file will have environment URL and other environment specific properties. 70 | 71 | 3) Capabilities : This folder will contain Browser, iOS, Android etc specific properties in the separate files as per our need. Please refer to sample project 'orange-hrm' for more details. 72 | 73 | 74 | ### XML file configurations 75 | TestNG xml file gives facility to execute test scripts as per our requirement. We need to provide the parameters which is mandatory for the execution of scripts and also as per our need 76 | 1) Parallel execution threads control: 77 | ```xml 78 | 79 | ``` 80 | 2) Provide Feature File/Folder Path: 81 | ```xml 82 | 83 | ``` 84 | 3) Provide Glue code package name where page object classes are created: 85 | ```xml 86 | 87 | ``` 88 | 4) Tag based execution - Provide the tag which need to include in execution: 89 | ```xml 90 | 91 | ``` 92 | 5) Include Extent Cucumber reporting plugin : 93 | ```xml 94 | 95 | ``` 96 | 6) Select runner class Name to run test scripts **parallel** or **sequential** : 97 | 98 | 1) Parallel Execution 99 | ```xml 100 | 101 | ``` 102 | 2) Sequential Execution 103 | ```xml 104 | 105 | ``` 106 | 107 | ### How to write feature file 108 | Use one feature file for each page which covers all and any number of scenarios you want to cover for that respective page 109 | 1) As we are using tag based execution provides tag for scenarios e.g. @Sanity, @High etc. 110 | 2) Follow **Given** , **When**, **Then** format : 111 | 1) **Given** - Pre-requisite of the test case 112 | 2) **When** - Actions to be performed in that test script 113 | 3) **Then** - Result Validation 114 | 115 | Example: 116 | ``` 117 | @High 118 | Scenario: Verify admin login successful 119 | Given user navigate to orange hrm URL 120 | When uses enters user name as "Admin" and password as "admin123" and click on login button 121 | Then user should be able to see "Welcome Admin" message 122 | ``` 123 | 124 | ### Test Data 125 | 1) Static Data- Define static test data (Refer PersonData class) 126 | 2) Dynamic test data generation- use RandonNumber class to generate dynamic test data at run time 127 | 3) Provide test data to test scenario in following format 128 | ``` 129 | Examples: 130 | | name | password | welcome_text | 131 | | Admin | admin123 | Welcome Admin | 132 | ``` 133 | 134 | ### How to write Page Object Classes 135 | 1) Provide all web element at the start of each page class 136 | 1) **@FindBy** - tag used for web/windows application web element 137 | 2) **@AndroidFindBy** tag used for Android application web element 138 | 2) Create a method for all **GIVEN** keyword of **feature file** with tag **Given** in respective page 139 | 3) Create a method for all **WHEN** keyword of **feature file** with tag **When** in respective page 140 | 4) Create a method for all **THEN** keyword of **feature file** with tag **Then** in respective page 141 | 5) Use Assertions for validation purpose to compare actual and expected results 142 | 143 | ### Applitool Integration 144 | 1) Create Property file in src/test/resources/properties/framework/ApplitoolEyeConfig.properties 145 | 2) Add properties as EYE_ENABLE=TRUE and BATCH_NAME=Regression Suite 146 | 3) Set Applitool API Key in System Environmental variable with name "APPLITOOLS_API_KEY". Variable can be sent as TestNg Environmental parameter, Maven Parameter, Jenkins Parameter or can be set in Runner Machine. 147 | -------------------------------------------------------------------------------- /orange-hrm/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | /target/ 7 | /.classpath 8 | /.project 9 | .project 10 | /.settings/ 11 | /bin/ 12 | /test-output 13 | /logs 14 | index.html 15 | 16 | # BlueJ files 17 | *.ctxt 18 | 19 | # Mobile Tools for Java (J2ME) 20 | .mtj.tmp/ 21 | 22 | # Package Files # 23 | *.jar 24 | *.war 25 | *.nar 26 | *.ear 27 | *.zip 28 | *.tar.gz 29 | *.rar 30 | 31 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 32 | hs_err_pid* -------------------------------------------------------------------------------- /orange-hrm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.orangehrm 4 | orange-hrm 5 | 0.0.2 6 | 7 | 8 | 1.8 9 | 1.8 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-surefire-plugin 19 | 2.14.1 20 | 21 | 22 | 23 | src/test/resources/${testNgFileName} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | io.github.innovativeqalab 34 | test-automation-framework 35 | 1.0.3 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /orange-hrm/src/test/java/com/orangehrm/ApplitoolConfig.java: -------------------------------------------------------------------------------- 1 | package com.orangehrm; 2 | 3 | import org.iqa.suite.commons.applitool.IConfigListner; 4 | 5 | import com.applitools.eyes.config.Configuration; 6 | import com.applitools.eyes.selenium.BrowserType; 7 | import com.applitools.eyes.visualgrid.model.DeviceName; 8 | import com.applitools.eyes.visualgrid.model.ScreenOrientation; 9 | 10 | public class ApplitoolConfig implements IConfigListner{ 11 | 12 | @Override 13 | public Configuration getApplitoolConfig(Configuration config) { 14 | 15 | config.addBrowser(800, 600, BrowserType.CHROME); 16 | config.addBrowser(700, 500, BrowserType.FIREFOX); 17 | config.addDeviceEmulation(DeviceName.iPhone_X, ScreenOrientation.PORTRAIT); 18 | 19 | return config; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /orange-hrm/src/test/java/com/orangehrm/pages/mobile/HomePage.java: -------------------------------------------------------------------------------- 1 | package com.orangehrm.pages.mobile; 2 | 3 | import org.iqa.test.base.BasePageMobile; 4 | import org.openqa.selenium.WebElement; 5 | import org.testng.Assert; 6 | 7 | import io.appium.java_client.pagefactory.AndroidFindBy; 8 | import io.cucumber.java.en.Then; 9 | 10 | public class HomePage extends BasePageMobile { 11 | 12 | //BasePage provides driver object, logger object 13 | 14 | @AndroidFindBy(xpath = "//android.widget.TextView[@text='Welcome Admin']") 15 | private WebElement welComeText; 16 | 17 | @Then("user should be able to see {string} message") 18 | public HomePage verifyWelcomeText(String strWelComeText) { 19 | System.out.println(driver.getPageSource()); 20 | logger.info("********** In verify welcome message method"); 21 | //logger.info("********** Run time data stored check - Title "+getRunTimeTestData("BrowserTitle")); 22 | Assert.assertEquals(welComeText.getText(), strWelComeText,"Test case failed because expected data not found"); 23 | return this; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /orange-hrm/src/test/java/com/orangehrm/pages/mobile/LoginPage.java: -------------------------------------------------------------------------------- 1 | package com.orangehrm.pages.mobile; 2 | 3 | import org.iqa.suite.commons.PropertyHolder; 4 | import org.iqa.test.base.BasePageMobile; 5 | import org.openqa.selenium.WebElement; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import io.appium.java_client.pagefactory.AndroidFindBy; 10 | import io.cucumber.java.en.Given; 11 | import io.cucumber.java.en.When; 12 | 13 | public class LoginPage extends BasePageMobile{ 14 | 15 | private static final Logger logger = LoggerFactory.getLogger(LoginPage.class); 16 | 17 | 18 | // @iOSXCUITFindBy(xpath = "//XCUIElementTypeImage[@name='ic_header_logo']") 19 | @AndroidFindBy(xpath = "//android.widget.EditText[@resource-id='txtUsername']") 20 | private WebElement userName; 21 | 22 | @AndroidFindBy(xpath = "//android.widget.EditText[@resource-id='txtPassword']") 23 | private WebElement password; 24 | 25 | @AndroidFindBy(xpath = "//android.widget.Button[@resource-id='btnLogin']") 26 | private WebElement loginButton; 27 | 28 | 29 | 30 | @Given("user navigate to orange hrm URL") 31 | public LoginPage navigateToOrangeHrmApplication() 32 | { 33 | String ENVIRONMENT = PropertyHolder.testSuiteConfigurationProperties.getProperty("ENVIRONMENT"); 34 | driver.get(PropertyHolder.testSuiteConfigurationProperties.getProperty(ENVIRONMENT+"_URL")); 35 | 36 | 37 | try { 38 | Thread.sleep(8000); 39 | } catch (InterruptedException e) { 40 | // TODO Auto-generated catch block 41 | e.printStackTrace(); 42 | } 43 | 44 | System.out.println(driver.getPageSource()); 45 | //setRunTimeTestData("BrowserTitle", driver.getTitle()); 46 | return this; 47 | } 48 | 49 | @When("uses enters user name as {string} and password as {string} and click on login button") 50 | public void loginForSuccess(String userName, String password) 51 | { 52 | logger.info("********** In verify welcome message method"); 53 | this.userName.sendKeys(userName); 54 | this.password.sendKeys(password); 55 | this.loginButton.click(); 56 | try { 57 | Thread.sleep(8000); 58 | } catch (InterruptedException e) { 59 | // TODO Auto-generated catch block 60 | e.printStackTrace(); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /orange-hrm/src/test/java/com/orangehrm/pages/web/HomePage.java: -------------------------------------------------------------------------------- 1 | package com.orangehrm.pages.web; 2 | 3 | import org.iqa.suite.commons.TestMetaData; 4 | import org.iqa.suite.commons.applitool.ApplitoolEyesWeb; 5 | import org.iqa.test.base.BasePageBrowser; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.support.FindBy; 8 | import org.testng.Assert; 9 | 10 | public class HomePage extends BasePageBrowser { 11 | 12 | //BasePage provides driver object, logger object 13 | 14 | @FindBy(id = "welcome") 15 | private WebElement welComeText; 16 | 17 | public HomePage verifyWelcomeText(String strWelComeText) { 18 | logger.info("********** In verify welcome message method"); 19 | logger.info("********** Run time data stored check - Title "+getRunTimeTestData("BrowserTitle")); 20 | Assert.assertEquals(welComeText.getText(), strWelComeText,"Test case failed because expected data not found"); 21 | return this; 22 | } 23 | 24 | public HomePage isPageLoaded() { 25 | if (TestMetaData.getTestTags().contains("@ScreenValidation") && ApplitoolEyesWeb.enabled) { 26 | ApplitoolEyesWeb.getEyes().checkWindow("Home Page"); 27 | } 28 | return this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /orange-hrm/src/test/java/com/orangehrm/pages/web/LoginPage.java: -------------------------------------------------------------------------------- 1 | package com.orangehrm.pages.web; 2 | 3 | import org.iqa.suite.commons.PropertyHolder; 4 | import org.iqa.suite.commons.TestMetaData; 5 | import org.iqa.suite.commons.applitool.ApplitoolEyesWeb; 6 | import org.iqa.test.base.BasePageBrowser; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.support.FindBy; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | public class LoginPage extends BasePageBrowser{ 13 | 14 | private static final Logger logger = LoggerFactory.getLogger(LoginPage.class); 15 | 16 | 17 | @FindBy(xpath="//input[@name='username']") 18 | private WebElement userName; 19 | 20 | @FindBy(xpath="//input[@name='password']") 21 | private WebElement password; 22 | 23 | @FindBy(xpath="//*[@type='submit']") 24 | private WebElement loginButton; 25 | 26 | @FindBy(xpath="//span[normalize-space()='Admin']") 27 | private WebElement adminTab; 28 | 29 | 30 | 31 | public LoginPage navigateToOrangeHrmApplication() 32 | { 33 | String ENVIRONMENT = PropertyHolder.testSuiteConfigurationProperties.getProperty("ENVIRONMENT"); 34 | driver.manage().window().maximize(); 35 | driver.get(PropertyHolder.testSuiteConfigurationProperties.getProperty(ENVIRONMENT+"_URL")); 36 | logger.info("======== Window size : "+driver.manage().window().getSize()); 37 | 38 | 39 | try { 40 | Thread.sleep(8000); 41 | } catch (InterruptedException e) { 42 | // TODO Auto-generated catch block 43 | e.printStackTrace(); 44 | } 45 | 46 | // System.out.println(driver.getPageSource()); 47 | //setRunTimeTestData("BrowserTitle", driver.getTitle()); 48 | return this; 49 | } 50 | 51 | public void loginForSuccess(String userName, String password) 52 | { 53 | logger.info("********** In verify welcome message method"); 54 | this.userName.sendKeys(userName); 55 | this.password.sendKeys(password); 56 | this.loginButton.click(); 57 | } 58 | 59 | public LoginPage isPageLoaded() { 60 | 61 | if (TestMetaData.getTestTags().contains("@ScreenValidation") && ApplitoolEyesWeb.enabled) { 62 | ApplitoolEyesWeb.getEyes().checkWindow("Login Page"); 63 | } 64 | 65 | return this; 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /orange-hrm/src/test/java/com/orangehrm/step_def/api/ApiSteps.java: -------------------------------------------------------------------------------- 1 | package com.orangehrm.step_def.api; 2 | 3 | import org.iqa.suite.commons.ApiUtils; 4 | import org.iqa.suite.commons.ExtentLogger; 5 | import org.json.JSONObject; 6 | import org.testng.Assert; 7 | 8 | import com.aventstack.extentreports.Status; 9 | import com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter; 10 | 11 | import io.cucumber.java.en.Given; 12 | import io.cucumber.java.en.Then; 13 | import io.cucumber.java.en.When; 14 | import io.restassured.response.Response; 15 | 16 | public class ApiSteps extends ApiUtils { 17 | 18 | private static final ExtentLogger extentLogger = new ExtentLogger(); 19 | private static JSONObject queryParams = new JSONObject(); 20 | private static JSONObject headerParams = new JSONObject(); 21 | private static ThreadLocal response = new ThreadLocal<>(); 22 | private static ThreadLocal strRequest = new ThreadLocal<>(); 23 | 24 | @Given("Test case id is {string}") 25 | public void test_case_id_is(String tc_id) { 26 | 27 | //ExtentCucumberAdapter.getCurrentStep().log(Status.INFO,"********* Test case ID: " + tc_id); 28 | } 29 | 30 | @Given("base URI is {string}") 31 | public void base_URI_is(String baseURI) { 32 | setBaseURI(baseURI); 33 | //ExtentCucumberAdapter.getCurrentStep().log(Status.INFO,"Base URI set as : " + baseURI); 34 | } 35 | 36 | @Given("request query params are {string}") 37 | public void request_query_params_are(String strQueryParams) { 38 | String[] strQueryParamsArr = strQueryParams.split("="); 39 | queryParams.put(strQueryParamsArr[0], strQueryParamsArr[1]); 40 | // extentLogger.info( 41 | // "*********INFO : Request query param added : " + strQueryParamsArr[0] + "=" + strQueryParamsArr[1]); 42 | } 43 | 44 | @Given("request header key is {string} and value is {string}") 45 | public void request_header_key_is_and_value_is(String headerKey, String headerValue) { 46 | headerParams.put(headerKey, headerValue); 47 | //extentLogger.info("*********INFO : Request header key :" + headerKey + " and header value : " + headerValue); 48 | } 49 | 50 | @Given("request is {string}") 51 | public void request_is(String request) { 52 | request = "{\"name\": \"Prashant\",\"job\": \"Tester\"}"; 53 | strRequest.set(request); 54 | //extentLogger.info("*********INFO : Request body is : " + strRequest.get()); 55 | } 56 | 57 | @When("user executes http {string} method with endpoint {string}") 58 | public void user_executes_http_method_with_endpoint(String method, String path) { 59 | 60 | if (method.equalsIgnoreCase("GET")) { 61 | response.set(httpGet(queryParams, path)); 62 | } else if (method.equalsIgnoreCase("POST")) { 63 | // response.set(httpPost(headerParams, queryParams, method, path)); 64 | response.set(httpPost(headerParams, strRequest.get(), path)); 65 | //extentLogger.info("*********INFO : Post Http Method executed for endpoint- " + path); 66 | } 67 | } 68 | 69 | @Then("user verifies status code as {int}") 70 | public void user_verifies_status_code_as(int expectedStatusCode) { 71 | Assert.assertEquals(getStatusCode(response.get()), expectedStatusCode, getBasePath()); 72 | int actualStatusCode = getStatusCode(response.get()); 73 | if (actualStatusCode == expectedStatusCode) { 74 | //extentLogger.info("*********INFO : Verified Response status code as expected - " + actualStatusCode); 75 | } else { 76 | //extentLogger.fail("*********ERROR : Status code mismatch!!! Expected : " + expectedStatusCode + " Actual: " 77 | //+ actualStatusCode); 78 | Assert.fail("Status code mismatch!!!"); 79 | } 80 | } 81 | 82 | @Then("user verifies response as {string}") 83 | public void user_verifies_response_as(String expectedResponse) { 84 | 85 | } 86 | 87 | @Then("user verifies response value of node {string} as {string}") 88 | public void user_verifies_response_value_of_node_as(String string, String string2) { 89 | 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /orange-hrm/src/test/java/com/orangehrm/step_def/web/LoginSteps.java: -------------------------------------------------------------------------------- 1 | package com.orangehrm.step_def.web; 2 | 3 | import com.orangehrm.pages.web.HomePage; 4 | import com.orangehrm.pages.web.LoginPage; 5 | 6 | import io.cucumber.java.en.Given; 7 | import io.cucumber.java.en.Then; 8 | import io.cucumber.java.en.When; 9 | 10 | public class LoginSteps { 11 | 12 | 13 | @Given("user navigate to orange hrm URL") 14 | public void navigateToOrangeHrmSite() 15 | { 16 | new LoginPage().navigateToOrangeHrmApplication().isPageLoaded(); 17 | } 18 | 19 | @When("uses enters user name as {string} and password as {string} and click on login button") 20 | public void login(String userName, String password) 21 | { 22 | new LoginPage().loginForSuccess(userName, password); 23 | } 24 | 25 | @Then("user should be able to see {string} message") 26 | public void verifyWelcomeText(String strWelComeText) { 27 | new HomePage().isPageLoaded().verifyWelcomeText(strWelComeText); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/ApiTestNg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/WebTestNg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/extent.properties: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------- 2 | # Cucumber-Extent-Adapter Configurations 3 | #--------------------------------------------------------- 4 | 5 | extent.reporter.spark.start=true 6 | #extent.reporter.html.start=false 7 | #extent.reporter.pdf.start=false 8 | #extent.reporter.klov.start=false 9 | #extent.reporter.json.start=false 10 | 11 | extent.reporter.spark.out=test-output/Extent-Report/ExtentSpark.html 12 | #extent.reporter.html.out=test-output/Extent-Report/ExtentHtml.html 13 | #extent.reporter.pdf.out=test-output/Extent-Report/ExtentPdf.pdf 14 | #extent.reporter.json.out=test-output/Extent-Report/ExtentJson.json 15 | 16 | #test,exception,category,device,author,log,dashboard - default order 17 | #extent.reporter.spark.vieworder=dashboard,test,category,exception,author,device,log 18 | 19 | 20 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/feature/AddUser.feature: -------------------------------------------------------------------------------- 1 | Feature: Add User 2 | I want to use this template for my feature file 3 | 4 | @Web 5 | Scenario: Verify admin login successful 6 | Given user navigate to orange hrm URL 7 | When uses enters user name as "Admin" and password as "admin123" and click on login button 8 | Then user should be able to see "Welcome Admin" message 9 | 10 | @Web 11 | Scenario Outline: Verify admin login successful with examples 12 | Given user navigate to orange hrm URL 13 | When uses enters user name as "" and password as "" and click on login button 14 | Then user should be able to see "" message 15 | 16 | Examples: 17 | | name | password | welcome_text | 18 | | Admin | admin123 | Welcome Admi | 19 | | Admin | admin123 | Welcome Admin | 20 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/feature/Api.feature: -------------------------------------------------------------------------------- 1 | Feature: API Test 2 | 3 | @Api @SmokeTest @GET 4 | Scenario Outline: To verify user is able to execute HTTP POST call for given API 5 | Given Test case id is "TC_ID_01" 6 | And base URI is "https://reqres.in/" 7 | And request query params are "page=2" 8 | When user executes http "GET" method with endpoint "api/users" 9 | Then user verifies status code as 200 10 | 11 | 12 | 13 | @Api @SmokeTest @POST 14 | 15 | Scenario Outline: To verify user is able to execute HTTP POST call for given API 16 | Given Test case id is "TC_ID_01" 17 | And base URI is "https://reqres.in/" 18 | And request header key is "content-type" and value is "application/json" 19 | And request is "" 20 | When user executes http "POST" method with endpoint "api/users" 21 | Then user verifies status code as 202 22 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/feature/Login.feature: -------------------------------------------------------------------------------- 1 | Feature: User Login 2 | I want to use this template for my feature file 3 | 4 | @Web @High @ScreenValidation 5 | Scenario: Verify admin login successful 6 | Given user navigate to orange hrm URL 7 | When uses enters user name as "Admin" and password as "admin123" and click on login button 8 | Then user should be able to see "Welcome Admin" message 9 | 10 | @Web @SanityTest @Low @ScreenValidation 11 | Scenario Outline: Verify admin login successful with examples 12 | Given user navigate to orange hrm URL 13 | When uses enters user name as "" and password as "" and click on login button 14 | Then user should be able to see "" message 15 | 16 | Examples: 17 | | name | password | welcome_text | 18 | | Admin | admin123 | Welcome Admi | 19 | | Admin | admin123 | Welcome Admin | 20 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/help/Commands.txt: -------------------------------------------------------------------------------- 1 | Install Appium Command Line - Ref - https://www.techaheadcorp.com/blog/how-to-install-appium-on-mac/ 2 | brew install npm 3 | npm install carthage 4 | npm install -g appium 5 | npm install appium-doctor -g 6 | Sudo gem install xcpretty 7 | brew install libimobiledevice –HEAD 8 | npm install -g ios-deploy 9 | 10 | Set ANDROID_HOME and JAVA_HOME 11 | 12 | Get List of all packages from device 13 | adb shell pm list packages | grep chrome 14 | 15 | Get path from package file 16 | adb shell pm path com.android.chrome 17 | 18 | Pull APK from device 19 | adb pull /data/app/com.android.chrome-fUINtz4zbfSoo0x70JzTfw==/base.apk 20 | 21 | Extract Main activity or Launcher activity from APK file 22 | aapt dump xmltree base.apk AndroidManifest.xml | grep Main -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/help/android_emulator_node_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "capabilities": [ 3 | { 4 | "browserName": "Android", 5 | "maxInstances": 1, 6 | "platform": "Android", 7 | "uuid": "emulator-5554" 8 | 9 | } 10 | ], 11 | "configuration": { 12 | "cleanUpCycle": 2000, 13 | "timeout": 30000, 14 | "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", 15 | "url":"http://localhost:4000/wd/hub", 16 | "host": "localhost", 17 | "maxSession": 1, 18 | "register": true, 19 | "registerCycle": 5000, 20 | "hubPort": 4444, 21 | "hubHost": "localhost" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/help/android_emulator_node_start.sh: -------------------------------------------------------------------------------- 1 | appium -p 4001 --nodeconfig android_mi2_node_config.json --bootstrap-port 5001 --default-capabilities '{"udid": "emulator-5554"}' -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/help/android_mi2_node_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "capabilities": [ 3 | { 4 | "browserName": "Android", 5 | "maxInstances": 1, 6 | "platform": "Android", 7 | "uuid": "1684c499" 8 | 9 | } 10 | ], 11 | "configuration": { 12 | "cleanUpCycle": 2000, 13 | "timeout": 30000, 14 | "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", 15 | "url":"http://localhost:4000/wd/hub", 16 | "host": "localhost", 17 | "maxSession": 1, 18 | "register": true, 19 | "registerCycle": 5000, 20 | "hubPort": 4444, 21 | "hubHost": "localhost" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/help/android_mi2_node_start.sh: -------------------------------------------------------------------------------- 1 | appium -p 4000 --nodeconfig android_mi2_node_config.json --bootstrap-port 5000 --default-capabilities '{"udid": "1684c499"}' 2 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/help/chrome_node.sh: -------------------------------------------------------------------------------- 1 | java -Dwebdriver.chrome.driver=chromedriver -jar selenium-server-standalone-3.141.59.jar -role node -hub http://localhost:4444/grid/register -browser browserName=chrome,version=84 -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/properties/capabilities/.gitignore: -------------------------------------------------------------------------------- 1 | /AndroidCapabilities.properties 2 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/properties/capabilities/BrowserCapabilities.properties: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------- 2 | # Browser Capabilities 3 | #--------------------------------------------------------- 4 | 5 | # Remote Execution (If Driver = REMOTE) 6 | #--------------------------------------------------------- 7 | browserName=chrome 8 | #platform=Windows 10 9 | #version=latest 10 | 11 | #Below capability can be used for Saucelabs execution 12 | #--------------------------------------------------------- 13 | #screenResolution=1680x1050 14 | 15 | #https://docs.saucelabs.com/dev/w3c-webdriver-capabilities/ 16 | 17 | 18 | ## READ ME 19 | # Capabilities Precedence will be given to ENVIRONMENT > PARAMETER > PROPERTIES is passed 20 | # ENVIRONMENT variable can be set via CI tool 21 | # ex. 22 | # Jenkins {Inject env variable in build process} 23 | # GitLab {GitLab variables} 24 | # Code {Java - System.setenv()} 25 | # PARAMETER variable can be set via build tool 26 | # ex. 27 | # maven {mvn test -DDRIVER=BROWSER} 28 | # PROPERTIES framework supported propery files will be used 29 | # ex. SuiteRuntimeProperty.properties. iOSCapabilities.properties, BrowserCapabilities.properties, AndroidCapabilities.properties -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/properties/capabilities/iOSCapabilities.properties: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------- 2 | # iOS Capabilities 3 | #--------------------------------------------------------- 4 | bundleId= 5 | platformName=iOS 6 | platformVersion= 7 | deviceName=iPhone 12 Pro Max 8 | automationName=XCUITest 9 | udid= 10 | app=storage:filename= 11 | -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/properties/framework/ApplitoolEyeConfig.properties: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------- 2 | # Applitools Eyes Configurations 3 | #--------------------------------------------------------- 4 | #EYE_ENABLE=TRUE/FALSE 5 | EYE_ENABLE=FALSE 6 | BATCH_NAME=Regression Suite 7 | APPLITOOL_CONFIG_PACKAGE=com.orangehrm 8 | APPLITOOLS_API_KEY= -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/properties/framework/FrameworkConfig.properties: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------- 2 | # AUT [Application Under Test] Configurations 3 | #--------------------------------------------------------- 4 | #AUT should have values from => [ WEB/ANDROID/IOS/API_ONLY] 5 | #WEB : This can be configured for WEB Automation [Along with API Automation if needed]. 6 | #ANDROID/IOS : This can be configured for MOBILE Automation [Along with API Automation if needed]. 7 | #API_ONLY : This can be configured for API Automation only. 8 | AUT=WEB 9 | 10 | #--------------------------------------------------------- 11 | # WebDriver/AppiumDriver Configurations 12 | #--------------------------------------------------------- 13 | #DRIVER should have values from => [REMOTE/BROWSER] 14 | #REMOTE : This can be configured for Remote execution where huburl is mandatory and grid/slave set should be done before execution 15 | #BROWSER : This can be configured for Local execution where browser details and configurations are mandatory 16 | DRIVER=REMOTE 17 | #--------------------------------------------------------- 18 | # Local Execution (If DRIVER = BROWSER) 19 | #--------------------------------------------------------- 20 | # browser [chrome/ie/firefox etc] 21 | browser=chrome 22 | #Please provide here respective browser driver executable path 23 | DRIVER_EXECUTABLE_PATH=/Users/********/Documents/Selenium/chromedriver 24 | DRIVER_PROPERTY_NAME=webdriver.chrome.driver 25 | 26 | #--------------------------------------------------------- 27 | # Remote Execution (If DRIVER = REMOTE) 28 | #--------------------------------------------------------- 29 | #For REMOTE mode hubUrl is mandatory and grid/slave set up should be done 30 | #Below can be Grid/Hub URL or Saucelabs URL or Appium URL 31 | #hubUrl=https://sso-fdc-qa-***.***:***@ondemand.*.saucelabs.com:443/wd/hub 32 | hubUrl=http://localhost:4444/wd/hub 33 | 34 | #--------------------------------------------------------- 35 | # READ ME - Capabilities 36 | #--------------------------------------------------------- 37 | # Please set Desired capabilities in respective property files in src/test/resources/properties/capabilities folder 38 | # Browser - BrowserCapabilities.properties 39 | # Android - AndroidCapabilities.properties 40 | # iOS - iOSCapabilities.properties 41 | 42 | #--------------------------------------------------------- 43 | # READ ME - Properties Precedence 44 | #--------------------------------------------------------- 45 | # Precedence will be given to ENVIRONMENT > PARAMETER > PROPERTIES 46 | # ENVIRONMENT variable can be set via CI tool 47 | # ex. 48 | # Jenkins {Inject env variable in build process} 49 | # GitLab {GitLab variables} 50 | # Code {Java - System.setenv()} 51 | # PARAMETER variable can be set via build tool 52 | # ex. 53 | # maven {mvn test -DDRIVER=BROWSER} 54 | # PROPERTIES framework supported propery files will be used 55 | # ex. SuiteRuntimeProperty.properties. iOSCapabilities.properties, BrowserCapabilities.properties, AndroidCapabilities.properties -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/properties/userDefined/Environment.properties: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------- 2 | # Test Execution Environment Configurations 3 | #--------------------------------------------------------- 4 | #ENVIRONMENT is where we are planning to execute Test cases. 5 | #e.g. DEV, TEST, QA, STAGE, PROD 6 | ENVIRONMENT=QA -------------------------------------------------------------------------------- /orange-hrm/src/test/resources/properties/userDefined/QAEnvironmentConfig.properties: -------------------------------------------------------------------------------- 1 | #QA_URL - QA is environment prefix, it can be configures in Environment.properties 2 | # or can be set to System properties by using System.setProperty("Environment","QA"). This can also be maven parameter 3 | # while using environment specific parameter it can be used as 4 | #String environment = PropertyHolder.generalProperties.get("Environment"); //it will return QA for example. 5 | #String url = PropertyHolder.generalProperties.get(environment+"_URL"); //Life is all about adjustment 6 | QA_URL=https://opensource-demo.orangehrmlive.com/ 7 | 8 | # Database list for information separated with a comma 9 | QA_databases=mysql1,mysql2,oracle1 10 | 11 | #Few sample configurations steps are provided below. Please use as per requirements 12 | #Ex. QA_mysql1.url in this please mention Environment name at the start and then Database name and .url and so on. 13 | # sample configuration for mysql1 14 | QA_mysql1.url= 15 | QA_mysql1.user= 16 | QA_mysql1.password= 17 | QA_mysql1.driver= 18 | QA_mysql1.poolsize= 19 | # sample configuration for mysql2 20 | QA_mysql2.url= 21 | QA_mysql2.user= 22 | QA_mysql2.password= 23 | QA_mysql2.driver= 24 | QA_mysql2.poolsize= 25 | # sample configuration for oracle1 26 | QA_oracle1.url= 27 | QA_oracle1.user= 28 | QA_oracle1.password= 29 | QA_oracle1.driver= 30 | QA_oracle1.poolsize= -------------------------------------------------------------------------------- /test-automation-framework/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | /target/ 7 | /.classpath 8 | /.project 9 | /.settings/ 10 | /bin/ 11 | /test-output 12 | /logs 13 | 14 | # BlueJ files 15 | *.ctxt 16 | 17 | # Mobile Tools for Java (J2ME) 18 | .mtj.tmp/ 19 | 20 | # Package Files # 21 | *.jar 22 | *.war 23 | *.nar 24 | *.ear 25 | *.zip 26 | *.tar.gz 27 | *.rar 28 | 29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 30 | hs_err_pid* -------------------------------------------------------------------------------- /test-automation-framework/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | io.github.innovativeqalab 4 | test-automation-framework 5 | 1.0.3 6 | jar 7 | test-automation-framework 8 | Functional Test Automation Framework 9 | https://github.com/innovativeQALab/iqa-automation-framework 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | org.seleniumhq.selenium 17 | selenium-java 18 | 3.141.59 19 | 20 | 21 | io.cucumber 22 | cucumber-java 23 | 7.2.3 24 | 25 | 26 | io.cucumber 27 | cucumber-testng 28 | 7.2.3 29 | 30 | 31 | tech.grasshopper 32 | extentreports-cucumber7-adapter 33 | 1.7.0 34 | 35 | 36 | io.rest-assured 37 | rest-assured 38 | 5.1.1 39 | 40 | 41 | io.appium 42 | java-client 43 | 7.2.0 44 | 45 | 46 | com.applitools 47 | eyes-selenium-java5 48 | 5.35.0 49 | 50 | 51 | com.applitools 52 | eyes-appium-java5 53 | 5.35.0 54 | 55 | 56 | org.apache.directory.studio 57 | org.apache.commons.io 58 | 2.4 59 | 60 | 61 | org.freemarker 62 | freemarker 63 | 2.3.30 64 | 65 | 66 | org.reflections 67 | reflections 68 | 0.10.2 69 | 70 | 71 | org.mongodb 72 | mongo-java-driver 73 | 3.12.3 74 | 75 | 76 | org.slf4j 77 | slf4j-log4j12 78 | 1.7.30 79 | 80 | 81 | com.zaxxer 82 | HikariCP 83 | 4.0.3 84 | 85 | 86 | org.json 87 | json 88 | 20220320 89 | 90 | 91 | mysql 92 | mysql-connector-java 93 | 8.0.29 94 | 95 | 96 | com.oracle.database.jdbc 97 | ojdbc8 98 | 21.6.0.0.1 99 | 100 | 101 | org.awaitility 102 | awaitility 103 | 4.2.0 104 | 105 | 106 | 112 | 113 | 114 | ossrh 115 | https://s01.oss.sonatype.org/content/repositories/snapshots 116 | 117 | 118 | ossrh 119 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 120 | 121 | 122 | 123 | scm:git:git://github.com/innovativeQALab/iqa-automation-framework.git 124 | scm:git:git@github.com:innovativeQALab/innovativeQALab.git 125 | https://github.com/innovativeQALab/iqa-automation-framework 126 | HEAD 127 | 128 | 129 | 130 | 131 | org.sonatype.plugins 132 | nexus-staging-maven-plugin 133 | 1.6.7 134 | true 135 | 136 | ossrh 137 | https://s01.oss.sonatype.org/ 138 | true 139 | 140 | 141 | 142 | org.apache.maven.plugins 143 | maven-release-plugin 144 | 2.5.3 145 | 146 | true 147 | false 148 | release 149 | deploy 150 | 151 | 152 | 153 | org.apache.maven.plugins 154 | maven-gpg-plugin 155 | 156 | 157 | sign-artifacts 158 | verify 159 | 160 | sign 161 | 162 | 163 | 165 | 166 | --pinentry-mode 167 | loopback 168 | 169 | 170 | 171 | 172 | 173 | 174 | org.apache.maven.plugins 175 | maven-source-plugin 176 | 2.2.1 177 | 178 | 179 | attach-sources 180 | 181 | jar-no-fork 182 | 183 | 184 | 185 | 186 | 187 | org.apache.maven.plugins 188 | maven-javadoc-plugin 189 | 2.10.4 190 | 191 | UTF-8 192 | -Xdoclint:none 193 | 194 | 195 | 196 | attach-javadocs 197 | 198 | jar 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | The Apache License, Version 2.0 208 | http://www.apache.org/licenses/LICENSE-2.0.txt 209 | 210 | 211 | 212 | 213 | innovativeQALab 214 | innovativeQALab 215 | innovativeqalab@gmail.com 216 | 217 | 218 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/ApiUtils.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import org.json.JSONObject; 4 | 5 | import io.restassured.RestAssured; 6 | import io.restassured.http.Method; 7 | import io.restassured.response.Response; 8 | import io.restassured.specification.RequestSpecification; 9 | 10 | public class ApiUtils { 11 | 12 | /** 13 | * This method will set RestAssured baseURI 14 | * 15 | * @param String baseURI 16 | */ 17 | protected void setBaseURI(String baseURI) { 18 | RestAssured.baseURI = baseURI; 19 | } 20 | 21 | /** 22 | * This method will get RestAssured baseURI 23 | * 24 | * @return String baseURI 25 | */ 26 | protected String getBaseURI() { 27 | return RestAssured.baseURI; 28 | } 29 | 30 | /** 31 | * This method will set RestAssured basePath 32 | * 33 | * @param String basePath 34 | */ 35 | protected void setBasePath(String basePath) { 36 | RestAssured.basePath = basePath; 37 | } 38 | 39 | /** 40 | * This method will get RestAssured basePath 41 | * 42 | * @return String basePath 43 | */ 44 | protected String getBasePath() { 45 | return RestAssured.basePath; 46 | } 47 | 48 | /** 49 | * This method will return Http Request 50 | */ 51 | protected RequestSpecification httpRequest() { 52 | return RestAssured.given(); 53 | } 54 | 55 | /** 56 | * This method will return Http Request 57 | */ 58 | protected RequestSpecification httpRequest(JSONObject headerParams) { 59 | return RestAssured.given().headers(headerParams.toMap()); 60 | } 61 | 62 | /** 63 | * This method will return Http Request 64 | */ 65 | protected RequestSpecification httpRequest(JSONObject headerParams,String request) { 66 | return RestAssured.given().headers(headerParams.toMap()).body(request); 67 | } 68 | 69 | /** 70 | * This method will return Http Request set with headers and queryparams 71 | * 72 | * @return RequestSpecification request 73 | */ 74 | protected RequestSpecification httpRequest(JSONObject headerParams, JSONObject queryParams) { 75 | return RestAssured.given().headers(headerParams.toMap()).queryParams(queryParams.toMap()); 76 | } 77 | 78 | /** 79 | * This method will return Http Request set with headers,queryparams and request 80 | * 81 | * @return RequestSpecification request 82 | */ 83 | protected RequestSpecification httpRequest(JSONObject headerParams, JSONObject queryParams, String request) { 84 | return RestAssured.given().headers(headerParams.toMap()).queryParams(queryParams.toMap()).body(request); 85 | } 86 | 87 | /** 88 | * This method will execute REST Http GET type method 89 | * 90 | * @param String path/endpoint 91 | * @return Response response 92 | */ 93 | protected Response httpGet(String path) { 94 | return httpRequest().request(Method.GET, path); 95 | } 96 | 97 | /** 98 | * This method will execute REST Http GET type method request level headers 99 | * 100 | * @param String path/endpoint 101 | * @return Response response 102 | */ 103 | protected Response httpGet(JSONObject headerParams, String path) { 104 | return httpRequest(headerParams).request(Method.GET, path); 105 | } 106 | 107 | /** 108 | * This method will execute REST Http GET type method headers and query params 109 | * 110 | * @param String path/endpoint 111 | * @return Response response 112 | */ 113 | protected Response httpGet(JSONObject headerParams, JSONObject queryParams, String path) { 114 | return httpRequest(headerParams, queryParams).request(Method.GET, path); 115 | } 116 | 117 | /** 118 | * This method will execute REST Http POST type method 119 | * 120 | * @param String path/endpoint 121 | * @return Response response 122 | */ 123 | protected Response httpPost(String path) { 124 | return httpRequest().request(Method.POST, path); 125 | } 126 | 127 | /** 128 | * This method will execute REST Http POST type method 129 | * 130 | * @param JSONObject headerParams 131 | * @param JSONObject queryParams 132 | * @param String path/endpoint 133 | * @return Response response 134 | */ 135 | protected Response httpPost(JSONObject headerParams, JSONObject queryParams, String path) { 136 | return httpRequest(headerParams, queryParams).request(Method.POST, path); 137 | } 138 | 139 | /** 140 | * This method will execute REST Http POST type method 141 | * 142 | * @param JSONObject headerParams 143 | * @param JSONObject queryParams 144 | * @param String request 145 | * @param String path/endpoint 146 | * @return Response response 147 | */ 148 | protected Response httpPost(JSONObject headerParams, JSONObject queryParams, String request, String path) { 149 | return httpRequest(headerParams, queryParams, request).request(Method.POST, path); 150 | } 151 | 152 | /** 153 | * This method will execute REST Http POST type method 154 | * 155 | * @param JSONObject headerParams 156 | * @param JSONObject queryParams 157 | * @param String request 158 | * @param String path/endpoint 159 | * @return Response response 160 | */ 161 | protected Response httpPost(JSONObject headerParams, String request, String path) { 162 | return httpRequest(headerParams, request).request(Method.POST, path); 163 | } 164 | 165 | /** 166 | * http delete 167 | * 168 | * @param params params 169 | * @param path endpoint 170 | * @return response 171 | */ 172 | protected Response httpDelete(JSONObject params, String path) { 173 | return httpRequest(params).request(Method.DELETE, path); 174 | } 175 | 176 | /** 177 | * http put 178 | * 179 | * @param params params 180 | * @param path endpoint 181 | * @return response 182 | */ 183 | protected Response httpPut(JSONObject params, String path) { 184 | return httpRequest(params).request(Method.PUT, path); 185 | } 186 | 187 | /** 188 | * Get Status code 189 | * 190 | * @param response response 191 | * @return status code 192 | */ 193 | protected int getStatusCode(Response response) { 194 | return response.getStatusCode(); 195 | } 196 | 197 | /** 198 | * This method evaluates Json Path and returns node value 199 | * 200 | * @param response response 201 | * @return jsonPath 202 | */ 203 | protected String jsonPathEvaluator(Response response, String expectedNode) { 204 | return response.jsonPath().get(expectedNode); 205 | } 206 | 207 | } 208 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/AssertionFactory.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import org.testng.asserts.SoftAssert; 4 | 5 | public class AssertionFactory { 6 | 7 | private static ThreadLocal softAssertHolder = new ThreadLocal(); 8 | 9 | public static SoftAssert getSoftAssert() { 10 | return softAssertHolder.get(); 11 | } 12 | 13 | public static void setSoftAssert(SoftAssert softAssert) { 14 | softAssertHolder.set(softAssert); 15 | } 16 | 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/CustomProperties.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import java.util.Properties; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class CustomProperties extends Properties { 9 | 10 | private static final long serialVersionUID = 1L; 11 | private static final Logger logger = LoggerFactory.getLogger(CustomProperties.class); 12 | 13 | @Override 14 | public String getProperty(String key) { 15 | if (null != System.getenv(key)) { 16 | logger.debug("Property '" + key + "' fetched from System environment variable"); 17 | return System.getenv(key); 18 | } else if (null != System.getProperty(key)) { 19 | logger.debug("Property '" + key + "' fetched from System environment variable"); 20 | return System.getProperty(key); 21 | } else if (null != super.getProperty(key)) { 22 | logger.debug("Property '" + key + "' fetched from System environment variable"); 23 | return super.getProperty(key); 24 | } else { 25 | logger.debug("!!!!!!!!!ERROR Failed to fetch property '" + key + "' Please verify property is defined"); 26 | return null; 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/DBUtils.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.time.Duration; 7 | import java.util.Map; 8 | import java.util.concurrent.ConcurrentHashMap; 9 | import java.util.function.Function; 10 | 11 | import javax.sql.DataSource; 12 | 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import com.zaxxer.hikari.HikariConfig; 17 | import com.zaxxer.hikari.HikariDataSource; 18 | 19 | public class DBUtils { 20 | 21 | private final static Logger logger = LoggerFactory.getLogger(DBUtils.class); 22 | private final static Map DB_POOL_MAP = new ConcurrentHashMap<>(); 23 | 24 | /** 25 | * Method getConnection is used to fetch connection from DB_POOLMAP 26 | * 27 | * @param Connection conn 28 | * 29 | */ 30 | public static synchronized Connection getConnection(String dbName) { 31 | Connection conn = null; 32 | if (!DB_POOL_MAP.containsKey(dbName)) { 33 | createDataSource(dbName); 34 | } 35 | DataSource dataSource = DB_POOL_MAP.get(dbName); 36 | try { 37 | conn = dataSource.getConnection(); 38 | logger.info("Fetched connection from database pool"); 39 | } catch (SQLException e) { 40 | // TODO Auto-generated catch block 41 | logger.error("!!!!!!!!!! Exception occured while fetching connection from database pool"); 42 | e.printStackTrace(); 43 | } 44 | return conn; 45 | } 46 | 47 | /** 48 | * Method createDataSource is used for creating the data source 49 | * 50 | * @param String dbName - database name for which data source is to be created 51 | * 52 | */ 53 | private static void createDataSource(String dbName) { 54 | logger.info("Creating the DataSource for " + dbName); 55 | HikariConfig hikariConfig = getHikariConfig(dbName); 56 | HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig); 57 | DB_POOL_MAP.put(dbName, hikariDataSource); 58 | logger.info("DataSource added to Database Pool Map"); 59 | } 60 | 61 | /** 62 | * Method getHikariConfig is used to set Hikari configurations 63 | * 64 | * @param String dbName - database name for which Hikari configs are to be set 65 | * 66 | */ 67 | private static HikariConfig getHikariConfig(String dbName) { 68 | 69 | String environment = PropertyHolder.testSuiteConfigurationProperties.getProperty("ENVIRONMENT"); 70 | 71 | if (null == PropertyHolder.testSuiteConfigurationProperties.getProperty(environment + "_" + dbName + ".url")) { 72 | logger.error("!!!!!!!!!!!!!ERROR - Database not definied in user defined properties..."); 73 | } 74 | HikariConfig hikaConfig = new HikariConfig(); 75 | Function getValue = (key) -> PropertyHolder.testSuiteConfigurationProperties 76 | .getProperty(environment + "_" + dbName + "." + key).toString(); 77 | 78 | hikaConfig.setJdbcUrl(getValue.apply("url")); 79 | hikaConfig.setUsername(getValue.apply("user")); 80 | hikaConfig.setPassword(getValue.apply("password")); 81 | hikaConfig.setDriverClassName(getValue.apply("driver")); 82 | hikaConfig.setPoolName(dbName); 83 | hikaConfig.setMaximumPoolSize(Integer.parseInt(getValue.apply("poolsize"))); 84 | hikaConfig.setConnectionTimeout(Duration.ofSeconds(30).toMillis()); 85 | hikaConfig.setIdleTimeout(Duration.ofMinutes(2).toMillis()); 86 | return hikaConfig; 87 | } 88 | 89 | /** 90 | * Method executeSelectQuery is used to executing select queries 91 | * 92 | * @param String query - select query 93 | * @param String dbName - database name for which select query is to be executed 94 | * 95 | * @return ResultSet result 96 | */ 97 | public static ResultSet executeSelectQuery(String query, String dbName) { 98 | 99 | ResultSet result = null; 100 | try { 101 | Connection conn = DBUtils.getConnection(dbName); 102 | result = conn.createStatement().executeQuery(query); 103 | } catch (SQLException e) { 104 | // TODO Auto-generated catch block 105 | e.printStackTrace(); 106 | } 107 | return result; 108 | } 109 | 110 | /** 111 | * Method executeSelectQuery is used to executing select queries 112 | * 113 | * @param String query - select query 114 | * @param String dbName - database name for which Update or Delete queries are 115 | * to be executed 116 | * 117 | * @return int resultCount 118 | */ 119 | public static int executeUpdateOrDeleteQuery(String query, String dbName) { 120 | int resultCount = 0; 121 | try { 122 | Connection conn = DBUtils.getConnection(dbName); 123 | resultCount = conn.createStatement().executeUpdate(query); 124 | logger.info("****Result count " + resultCount); 125 | } catch (SQLException e) { 126 | // TODO Auto-generated catch block 127 | e.printStackTrace(); 128 | } 129 | return resultCount; 130 | } 131 | } -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/ExtentLogger.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import org.iqa.suite.commons.reporting.ExtentReportTestFactory; 4 | 5 | import com.aventstack.extentreports.MediaEntityBuilder; 6 | import com.aventstack.extentreports.Status; 7 | 8 | public class ExtentLogger { 9 | 10 | public ExtentLogger info(String message) { 11 | ExtentReportTestFactory.getTest().log(Status.INFO, message); 12 | return this; 13 | } 14 | 15 | @Deprecated 16 | public ExtentLogger error(String message) { 17 | ExtentReportTestFactory.getTest().fail(message); 18 | return this; 19 | } 20 | 21 | @Deprecated 22 | public ExtentLogger error(Throwable thorowable) { 23 | ExtentReportTestFactory.getTest().fail(thorowable); 24 | return this; 25 | } 26 | 27 | public ExtentLogger fail(String message) { 28 | ExtentReportTestFactory.getTest().fail(message); 29 | return this; 30 | } 31 | 32 | public ExtentLogger fail(Throwable thorowable) { 33 | ExtentReportTestFactory.getTest().fail(thorowable); 34 | return this; 35 | } 36 | 37 | public ExtentLogger attachScreenshot() { 38 | ExtentReportTestFactory.getTest().log(Status.INFO, 39 | MediaEntityBuilder.createScreenCaptureFromBase64String(SeleniumUtils.getScreenshotAsBase64()).build()); 40 | return this; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/JavaUtils.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLDecoder; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class JavaUtils { 10 | private static final Logger logger = LoggerFactory.getLogger(JavaUtils.class); 11 | 12 | protected static String getClassFilePath(Class cls){ 13 | logger.info("******** getFilePath for class "+cls.getName()); 14 | String strSourceClassName = cls.getResource(cls.getSimpleName()+".class").getPath(); 15 | logger.info("*************** resource path is "+strSourceClassName); 16 | try { 17 | strSourceClassName = URLDecoder.decode(strSourceClassName,"UTF-8"); 18 | } catch (UnsupportedEncodingException e) { 19 | // TODO Auto-generated catch block 20 | e.printStackTrace(); 21 | } 22 | StringBuffer strFilePath = new StringBuffer(); 23 | strFilePath.append(strSourceClassName.subSequence(1, strSourceClassName.indexOf("com"))); 24 | strFilePath.append(cls.getName().replace(".","/")); 25 | strFilePath.append(".xlsx"); 26 | logger.info("Class path is - "+strFilePath); 27 | //return strFilePath.toString(); 28 | return strSourceClassName.replace(".class", ".xlsx"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/PropertyHolder.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | 9 | import org.iqa.suite.commons.applitool.ApplitoolEyesWeb; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | public class PropertyHolder { 14 | 15 | public static CustomProperties testSuiteConfigurationProperties = null; 16 | 17 | private static final Logger logger = LoggerFactory.getLogger(PropertyHolder.class); 18 | 19 | public static void loadPropertyFile(String propFilePath) throws IOException { 20 | if (null == testSuiteConfigurationProperties) 21 | testSuiteConfigurationProperties = new CustomProperties(); 22 | InputStream input = new FileInputStream(propFilePath); 23 | testSuiteConfigurationProperties.load(input); 24 | } 25 | 26 | public static void loadFrameworkConfig() { 27 | try { 28 | loadPropertyFile("src/test/resources/properties/framework/FrameworkConfig.properties"); 29 | logger.debug("FrameworkConfig.properties loaded."); 30 | 31 | } catch (FileNotFoundException e) { 32 | logger.error("!!!!! FrameworkConfig.properties" 33 | + " file Not found. \n Please create FrameworkConfig.properties to start with execution at location => src/test/resources/properties/framework/FrameworkConfig.properties."); 34 | e.printStackTrace(); 35 | logger.error("Exiting ..."); 36 | System.exit(-1); 37 | } catch (IOException e) { 38 | logger.error( 39 | "!!!!!!Error while loading property FrameworkConfig.properties file. \n Please check content of property file and try again."); 40 | e.printStackTrace(); 41 | System.exit(-1); 42 | } 43 | } 44 | 45 | public static void loadApplitoolConfig() { 46 | 47 | try { 48 | loadPropertyFile("src/test/resources/properties/framework/ApplitoolEyeConfig.properties"); 49 | logger.debug("ApplitoolEyeConfig.properties"); 50 | }catch (FileNotFoundException e) { 51 | logger.error("!!!!! ApplitoolEyeConfig.properties" 52 | + " file Not found. \n Please create ApplitoolEyeConfig.properties if you want to use Applitool at location => src/test/resources/properties/framework/ApplitoolEyeConfig.properties."); 53 | e.printStackTrace(); 54 | ApplitoolEyesWeb.enabled = false; 55 | } 56 | catch (IOException e) { 57 | logger.error( 58 | "!!!!!!Error while loading property ApplitoolEyeConfig.properties file. \n Please check content of property file and try again."); 59 | ApplitoolEyesWeb.enabled = false; 60 | 61 | } 62 | } 63 | 64 | public static void loadGeneralConfig() { 65 | File[] files = new File("src/test/resources/properties/userDefined").listFiles(); 66 | for (File file : files) { 67 | if (file.isDirectory()) { 68 | logger.error( 69 | "!!!!! Unexpected structure found : src/test/resources/properties/userDefined folder contain sub folders. It should contain only properties files. Load properties form sub folder is not yet implemented."); 70 | } else { 71 | try { 72 | loadPropertyFile(file.getAbsolutePath()); 73 | } catch (FileNotFoundException e) { 74 | logger.error("!!!!! " + file.getAbsolutePath() 75 | + " file Not found. \n Please create Environment.properties file if you want to configure exeuction environment at location => src/test/resources/properties/framework/userDefined."); 76 | e.printStackTrace(); 77 | // System.exit(-1); 78 | } catch (IOException e) { 79 | logger.error("Error while loading property " + file.getAbsolutePath() 80 | + " file. \n Please check content of property file and try again."); 81 | e.printStackTrace(); 82 | // System.exit(-1); 83 | } 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/SeleniumUtils.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import org.apache.commons.io.FileUtils; 6 | import org.iqa.test.webdriver_factory.WebDriverFactory; 7 | import org.openqa.selenium.OutputType; 8 | import org.openqa.selenium.TakesScreenshot; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | public class SeleniumUtils { 13 | private static final Logger logger = LoggerFactory.getLogger(SeleniumUtils.class); 14 | 15 | public static void takeScreenshot(String fileNameWithPath) { 16 | if (null == WebDriverFactory.getDriver()) { 17 | logger.info("!!!!!! Webdriver is null hence returning from SeleniumUtil > takeScreenShot()"); 18 | return; 19 | } 20 | logger.info("********** Taking screenshot at - " + fileNameWithPath); 21 | File scrFile = ((TakesScreenshot) WebDriverFactory.getDriver()).getScreenshotAs(OutputType.FILE); 22 | try { 23 | FileUtils.copyFile(scrFile, new File(fileNameWithPath)); 24 | } catch (IOException e) { 25 | logger.info("!!!!!!!!!! exception while taking screenshot"); 26 | e.printStackTrace(); 27 | } 28 | } 29 | 30 | public static String getScreenshotAsBase64() { 31 | if (null == WebDriverFactory.getDriver()) { 32 | logger.info("!!!!!! Webdriver is null hence returning from SeleniumUtil > takeScreenShot()"); 33 | return null; 34 | } 35 | logger.info("********** Taking screenshot as Base64 "); 36 | return ((TakesScreenshot) WebDriverFactory.getDriver()).getScreenshotAs(OutputType.BASE64); 37 | } 38 | 39 | /** 40 | * Returns OS Family name based on platform name 41 | * 42 | * @param platformProperty/* 43 | * @return String osFamilyName 44 | */ 45 | public static String getOsFamilyName(String platformProperty) { 46 | String platform = platformProperty.toLowerCase(); 47 | if (platform.contains("windows") || platform.contains("win")) { 48 | return "WINDOWS"; 49 | } else if (platform.contains("linux")) { 50 | return "LINUX"; 51 | } else if (platform.contains("mac")) { 52 | return "MAC"; 53 | } else if (platform.contains("ios")) { 54 | return "IOS"; 55 | } else if (platform.contains("android")) { 56 | return "ANDROID"; 57 | } else { 58 | throw new IllegalArgumentException( 59 | "!!! Platform property " + platformProperty + " is not currently supported with this version of framework!!!"); 60 | } 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/TestMetaData.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import io.cucumber.testng.FeatureWrapper; 7 | import io.cucumber.testng.PickleWrapper; 8 | 9 | public class TestMetaData { 10 | 11 | private static ThreadLocal pickleWrapper = new ThreadLocal<>(); 12 | private static ThreadLocal featureWrapper = new ThreadLocal<>(); 13 | 14 | public static PickleWrapper getPickleWrapper() { 15 | return pickleWrapper.get(); 16 | } 17 | 18 | public static void setPickleWrapper(PickleWrapper pickleWrapper) { 19 | TestMetaData.pickleWrapper.set(pickleWrapper); 20 | } 21 | 22 | public static FeatureWrapper getFeatureWrapper() { 23 | return featureWrapper.get(); 24 | } 25 | 26 | public static void setFeatureWrapper(FeatureWrapper featureWrapper) { 27 | TestMetaData.featureWrapper.set(featureWrapper); 28 | } 29 | 30 | public static void setTestTags(ThreadLocal> testTags) { 31 | TestMetaData.testTags = testTags; 32 | } 33 | 34 | private static ThreadLocal> testTags = new ThreadLocal<>(); 35 | 36 | public static void initialize() { 37 | testTags.set(new ArrayList()); 38 | } 39 | 40 | public static void setTestTags(List tags) { 41 | testTags.get().addAll(tags); 42 | } 43 | 44 | public static List getTestTags() { 45 | return new ArrayList<>(testTags.get()); //Immutable object return 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/applitool/ApplitoolEyesMobile.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons.applitool; 2 | 3 | import java.util.Set; 4 | 5 | import org.iqa.suite.commons.PropertyHolder; 6 | import org.reflections.Reflections; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import com.applitools.eyes.BatchInfo; 11 | import com.applitools.eyes.appium.Eyes; 12 | import com.applitools.eyes.config.Configuration; 13 | import com.applitools.eyes.selenium.StitchMode; 14 | 15 | public class ApplitoolEyesMobile { 16 | 17 | private static ThreadLocal eyes = new ThreadLocal<>(); 18 | private static Configuration config ; 19 | public static boolean enabled=false; 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(ApplitoolEyesMobile.class); 22 | 23 | 24 | private static void createApplitoolEyeConfig() { 25 | //runner = new ClassicRunner(new RunnerOptions().testConcurrency(5)); 26 | config = new Configuration(); 27 | } 28 | 29 | public static void setApplitoolCongfig(String applitoolApiKey) 30 | { 31 | 32 | createApplitoolEyeConfig(); 33 | Reflections reflections; 34 | reflections = new Reflections(PropertyHolder.testSuiteConfigurationProperties.getProperty("APPLITOOL_CONFIG_PACKAGE").toString()); 35 | 36 | Set> classes = reflections.getSubTypesOf(IConfigListner.class); 37 | Object[] arr = classes.toArray(); 38 | try { 39 | ((Class)arr[0]).newInstance().getApplitoolConfig(config); 40 | } catch (InstantiationException e) { 41 | // TODO Auto-generated catch block 42 | e.printStackTrace(); 43 | } catch (IllegalAccessException e) { 44 | // TODO Auto-generated catch block 45 | e.printStackTrace(); 46 | } 47 | config.setApiKey(applitoolApiKey); 48 | config.setStitchMode(StitchMode.CSS); 49 | config.setBatch(new BatchInfo(PropertyHolder.testSuiteConfigurationProperties.getProperty("BATCH_NAME").toString())); 50 | 51 | } 52 | 53 | public static Eyes getEyes() { 54 | 55 | if(!ApplitoolEyesMobile.enabled ) 56 | { 57 | System.out.println("!!!!!!!!!! Applitool eye either disabled or not configured corrctly. Plase check Applitool configuration in src/test/resources/properties/framework/ApplitoolEyeConfig.proprtis"); 58 | logger.error("!!!!!!!!!! Applitool eye either disabled or not configured corrctly. Plase check Applitool configuration in src/test/resources/properties/framework/ApplitoolEyeConfig.proprtis"); 59 | }else { 60 | 61 | } 62 | return eyes.get(); 63 | } 64 | 65 | public static Eyes getEyesForPageObject() { 66 | return eyes.get(); 67 | } 68 | 69 | public static Eyes createEyes() { 70 | if(ApplitoolEyesMobile.enabled ) 71 | { 72 | eyes.set(new Eyes()); 73 | eyes.get().setConfiguration(config); 74 | } 75 | return eyes.get(); 76 | } 77 | 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/applitool/ApplitoolEyesWeb.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons.applitool; 2 | 3 | import java.util.Set; 4 | 5 | import org.iqa.suite.commons.PropertyHolder; 6 | import org.reflections.Reflections; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import com.applitools.eyes.BatchInfo; 11 | import com.applitools.eyes.EyesRunner; 12 | import com.applitools.eyes.config.Configuration; 13 | import com.applitools.eyes.selenium.Eyes; 14 | import com.applitools.eyes.visualgrid.services.RunnerOptions; 15 | import com.applitools.eyes.visualgrid.services.VisualGridRunner; 16 | 17 | public class ApplitoolEyesWeb { 18 | 19 | private static final VisualGridRunner runner = new VisualGridRunner(new RunnerOptions().testConcurrency(20)); 20 | private static ThreadLocal eyes = new ThreadLocal<>(); 21 | private static Configuration config; 22 | public static boolean enabled = false; 23 | private static final Logger logger = LoggerFactory.getLogger(ApplitoolEyesWeb.class); 24 | 25 | private static void createApplitoolEyeConfig() { 26 | config = new Configuration(); 27 | } 28 | 29 | @SuppressWarnings("unchecked") 30 | public static void setApplitoolCongfig(String applitoolApiKey) { 31 | createApplitoolEyeConfig(); 32 | Reflections reflections; 33 | reflections = new Reflections( 34 | PropertyHolder.testSuiteConfigurationProperties.getProperty("APPLITOOL_CONFIG_PACKAGE").toString()); 35 | Set> classes = reflections.getSubTypesOf(IConfigListner.class); 36 | Object[] arr = classes.toArray(); 37 | try { 38 | ((Class) arr[0]).newInstance().getApplitoolConfig(config); 39 | } catch (InstantiationException e) { 40 | e.printStackTrace(); 41 | } catch (IllegalAccessException e) { 42 | e.printStackTrace(); 43 | } 44 | config.setApiKey(applitoolApiKey); 45 | config.setBatch( 46 | new BatchInfo(PropertyHolder.testSuiteConfigurationProperties.getProperty("BATCH_NAME").toString())); 47 | //config.setHostOS(PropertyHolder.testSuiteConfigurationProperties.getProperty("platform").toString()); 48 | } 49 | 50 | public static EyesRunner getApplitoolEyeRunner() { 51 | return runner; 52 | } 53 | 54 | public static Eyes getEyes() { 55 | 56 | if (!ApplitoolEyesWeb.enabled) { 57 | logger.info("!!!!!!!!!! Applitool eye either disabled or not configured corrctly." 58 | + "\n Please check Applitool configuration in src/test/resources/properties/framework/ApplitoolEyeConfig.proprtis"); 59 | logger.error("!!!!!!!!!! Applitool eye either disabled or not configured corrctly." 60 | + "\n Please check Applitool configuration in src/test/resources/properties/framework/ApplitoolEyeConfig.proprtis"); 61 | } else { 62 | } 63 | return eyes.get(); 64 | } 65 | 66 | public static Eyes getEyesForPageObject() { 67 | return eyes.get(); 68 | } 69 | 70 | public static Eyes createEyes() { 71 | if (ApplitoolEyesWeb.enabled) { 72 | eyes.set(new Eyes(runner)); 73 | eyes.get().setConfiguration(config); 74 | } 75 | return eyes.get(); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/applitool/ApplitoolsEyesUtils.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons.applitool; 2 | 3 | import org.iqa.suite.commons.PropertyHolder; 4 | import org.iqa.suite.commons.SeleniumUtils; 5 | import org.iqa.suite.commons.TestMetaData; 6 | import org.iqa.test.webdriver_factory.WebDriverFactory; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import com.applitools.eyes.TestResultsSummary; 11 | 12 | public class ApplitoolsEyesUtils { 13 | 14 | private static final Logger logger = LoggerFactory.getLogger(ApplitoolsEyesUtils.class); 15 | private static String AUT = null; 16 | private static String EYE_ENABLE = null; 17 | private static String APPLITOOLS_API_KEY = null; 18 | 19 | static { 20 | logger.debug("********* In ApplitoolsEyesUtils static block..."); 21 | AUT = PropertyHolder.testSuiteConfigurationProperties.getProperty("AUT").toString(); 22 | EYE_ENABLE = PropertyHolder.testSuiteConfigurationProperties.getProperty("EYE_ENABLE").toString(); 23 | APPLITOOLS_API_KEY = PropertyHolder.testSuiteConfigurationProperties.getProperty("APPLITOOLS_API_KEY") 24 | .toString(); 25 | } 26 | 27 | public static void setApplitoolEyeConfig() { 28 | if (null != EYE_ENABLE && new Boolean(EYE_ENABLE) == true) { 29 | if (AUT.equalsIgnoreCase("WEB")) { 30 | logger.info("********* Opening Applitool Eyes for Web"); 31 | ApplitoolEyesWeb.enabled = true; 32 | ApplitoolEyesWeb.setApplitoolCongfig(APPLITOOLS_API_KEY); 33 | logger.info("Applitools eyes configuration setup done."); 34 | } else if (AUT.equalsIgnoreCase("ANDROID") || AUT.equalsIgnoreCase("IOS")) { 35 | logger.info("********* Opening Applitool Eyes for Mobile"); 36 | ApplitoolEyesMobile.enabled = true; 37 | ApplitoolEyesMobile.setApplitoolCongfig(APPLITOOLS_API_KEY); 38 | logger.info("********* Applitool configuration setup done."); 39 | } else { 40 | logger.info("!!!!!!!!!!!!! Invalid AUT property value. Please provide correct value from {WEB,ANDROID,IOS}"); 41 | System.exit(1); 42 | } 43 | } 44 | } 45 | 46 | public static void openApplitoolEye() { 47 | if ((ApplitoolEyesWeb.enabled == true || ApplitoolEyesMobile.enabled) == true) { 48 | String platform = SeleniumUtils.getOsFamilyName(PropertyHolder.testSuiteConfigurationProperties.getProperty("platform").toString()); 49 | if (platform.equalsIgnoreCase("LINUX") || platform.equalsIgnoreCase("WINDOWS") || platform.equalsIgnoreCase("MAC")) { 50 | ApplitoolEyesWeb.createEyes().open(WebDriverFactory.getDriver(), 51 | TestMetaData.getFeatureWrapper().toString(), 52 | TestMetaData.getPickleWrapper().toString() + ":" 53 | + platform.toLowerCase());// ,new RectangleSize(1024, 751)); 54 | 55 | } else if (platform.equalsIgnoreCase("ANDROID") || platform.equalsIgnoreCase("IOS")) { 56 | ApplitoolEyesMobile.createEyes().open(WebDriverFactory.getDriver(), 57 | TestMetaData.getFeatureWrapper().toString(), 58 | TestMetaData.getPickleWrapper().toString() + ":" 59 | + platform.toLowerCase());// ,new RectangleSize(1024, 751)); 60 | } 61 | } 62 | } 63 | 64 | public static void closeApplitoolEye() { 65 | logger.info("****** Closing Applitools Eyes..."); 66 | if (ApplitoolEyesWeb.enabled == true && null != ApplitoolEyesWeb.getEyes() 67 | && ApplitoolEyesWeb.getEyes().getIsOpen()) { 68 | ApplitoolEyesWeb.getEyes().closeAsync(); 69 | 70 | } else if (ApplitoolEyesMobile.enabled == true && null != ApplitoolEyesMobile.getEyes() 71 | && ApplitoolEyesMobile.getEyes().getIsOpen()) { 72 | ApplitoolEyesMobile.getEyes().closeAsync(); 73 | } 74 | logger.info("****** Applitools Eyes closed."); 75 | } 76 | 77 | public static void applicationToolEyeWebGetAllTestResults() { 78 | TestResultsSummary testResultSummary = ApplitoolEyesWeb.getApplitoolEyeRunner().getAllTestResults(true); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/applitool/IConfigListner.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons.applitool; 2 | 3 | import com.applitools.eyes.config.Configuration; 4 | 5 | public interface IConfigListner { 6 | 7 | public Configuration getApplitoolConfig(Configuration config); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/database/DBConnection.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons.database; 2 | 3 | import java.sql.Connection; 4 | 5 | public class DBConnection { 6 | private boolean isActive; 7 | private Connection conn; 8 | 9 | public DBConnection(Connection connection, boolean isActive) { 10 | this.conn = connection; 11 | this.isActive = isActive; 12 | 13 | } 14 | 15 | public boolean isActive() { 16 | return isActive; 17 | } 18 | 19 | public void setActive(boolean isActive) { 20 | this.isActive = isActive; 21 | } 22 | 23 | public Connection getConn() { 24 | return conn; 25 | } 26 | 27 | public void setConn(Connection conn) { 28 | this.conn = conn; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/listeners/TestNGMethodInvocationListener.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons.listeners; 2 | 3 | import java.net.MalformedURLException; 4 | import java.util.HashMap; 5 | 6 | import org.iqa.suite.commons.AssertionFactory; 7 | import org.iqa.suite.commons.PropertyHolder; 8 | import org.iqa.suite.commons.SeleniumUtils; 9 | import org.iqa.suite.commons.TestMetaData; 10 | import org.iqa.suite.commons.applitool.ApplitoolsEyesUtils; 11 | import org.iqa.test.test_data.RuntimeTestDataHolder; 12 | import org.iqa.test.webdriver_factory.WebDriverFactory; 13 | import org.iqa.test.webdriver_factory.WebDriverManager; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | import org.testng.IInvokedMethod; 17 | import org.testng.IInvokedMethodListener; 18 | import org.testng.ITestResult; 19 | import org.testng.asserts.SoftAssert; 20 | 21 | import com.aventstack.extentreports.MediaEntityBuilder; 22 | import com.aventstack.extentreports.Status; 23 | import com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter; 24 | 25 | public class TestNGMethodInvocationListener implements IInvokedMethodListener { 26 | private static final Logger logger = LoggerFactory.getLogger(TestNGMethodInvocationListener.class); 27 | private SoftAssert softAssert = null; 28 | private static String AUT = null; 29 | 30 | public void beforeInvocation(IInvokedMethod method, ITestResult testResult) { 31 | 32 | if (method.isTestMethod()) { 33 | // Fetching Framework configuration : AUT[Application under Test] 34 | AUT = PropertyHolder.testSuiteConfigurationProperties.getProperty("AUT").toString().toUpperCase(); 35 | logger.info("******** In before invocation"); 36 | switch (AUT) { 37 | case "WEB": 38 | case "UI+API": 39 | try { 40 | WebDriverFactory.setDriver(WebDriverManager.CreateInstance()); 41 | WebDriverFactory.getDriver().manage().window().maximize(); 42 | logger.info("******** Driver object and test report instance created successfully"); 43 | } catch (MalformedURLException e) { 44 | logger.error("!!!!!!!! Exception occured while creating Driver object and test report instance "); 45 | e.printStackTrace(); 46 | } 47 | break; 48 | case "ANDROID": 49 | case "IOS": 50 | try { 51 | WebDriverFactory.setDriver(WebDriverManager.CreateInstance()); 52 | } catch (MalformedURLException e) { 53 | logger.error( 54 | "!!!!!!!! Exception occured while creating AppiumDriver object and test report instance"); 55 | e.printStackTrace(); 56 | } 57 | break; 58 | case "API_ONLY": 59 | break; 60 | 61 | default: 62 | logger.error("!!!!!!!! AUT property should have values from [WEB/ANDROID/IOS/API_ONLY]. Exiting..."); 63 | break; 64 | } 65 | softAssert = new SoftAssert(); 66 | AssertionFactory.setSoftAssert(softAssert); 67 | RuntimeTestDataHolder.setRunTimeTestData(new HashMap()); 68 | logger.info("********RuntimeTestDataHolder initialized."); 69 | TestMetaData.initialize(); 70 | logger.info("********TestMetaData initialized."); 71 | 72 | } 73 | } 74 | 75 | public void afterInvocation(IInvokedMethod method, ITestResult testResult) { 76 | if (method.isTestMethod()) { 77 | logger.info("******** In after invocation"); 78 | logger.info("******** Test Case Status " + testResult.isSuccess()); 79 | try { 80 | if (!AUT.equalsIgnoreCase("API_ONLY")) { 81 | if (!testResult.isSuccess()) { 82 | ExtentCucumberAdapter.getCurrentStep().log(Status.FAIL, MediaEntityBuilder 83 | .createScreenCaptureFromBase64String(SeleniumUtils.getScreenshotAsBase64()).build()); 84 | logger.debug("******** Screenshot attached to extent report"); 85 | } 86 | WebDriverFactory.getDriver().quit(); 87 | ApplitoolsEyesUtils.closeApplitoolEye(); 88 | } 89 | } catch (Exception e) { 90 | e.printStackTrace(); 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/mobile/AdbOperations.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons.mobile; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | 7 | public class AdbOperations { 8 | 9 | public static String installApplication(String strFullApkFileName){ 10 | return commandExecutor("adb install "+"\""+strFullApkFileName+"\""); //need to test this line of code on unix system once 11 | } 12 | 13 | public static String unInstallApplication(String strPackageName){ 14 | return commandExecutor("adb uninstall "+"\""+strPackageName+"\""); //need to test this line of code on unix system once 15 | } 16 | 17 | private static String commandExecutor(String strCommand){ 18 | 19 | String line,consoleOut=""; 20 | 21 | try { 22 | Process process = Runtime.getRuntime().exec(strCommand); 23 | BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); 24 | while((line=br.readLine())!=null){ 25 | consoleOut= consoleOut+line; 26 | } 27 | br.close(); 28 | } catch (IOException e) { 29 | e.printStackTrace(); 30 | System.out.println("Exception in executing command - "+e.getMessage()); //logger needs to be implemented 31 | consoleOut = null; 32 | } 33 | return consoleOut; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/suite/commons/reporting/ExtentReportTestFactory.java: -------------------------------------------------------------------------------- 1 | package org.iqa.suite.commons.reporting; 2 | 3 | import com.aventstack.extentreports.ExtentTest; 4 | import com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter; 5 | 6 | public class ExtentReportTestFactory { 7 | public static ExtentTest getTest() { 8 | return ExtentCucumberAdapter.getCurrentStep(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/base/BasePageBrowser.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.base; 2 | 3 | import java.time.Duration; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.iqa.suite.commons.ExtentLogger; 8 | import org.iqa.suite.commons.applitool.ApplitoolEyesWeb; 9 | import org.iqa.test.test_data.RuntimeTestDataHolder; 10 | import org.iqa.test.webdriver_factory.WebDriverFactory; 11 | import org.openqa.selenium.JavascriptExecutor; 12 | import org.openqa.selenium.NoSuchElementException; 13 | import org.openqa.selenium.WebDriver; 14 | import org.openqa.selenium.WebElement; 15 | import org.openqa.selenium.support.PageFactory; 16 | import org.openqa.selenium.support.ui.FluentWait; 17 | import org.openqa.selenium.support.ui.Wait; 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.testng.TestException; 21 | 22 | import com.applitools.eyes.selenium.Eyes; 23 | 24 | public class BasePageBrowser { 25 | 26 | protected Wait fluentwait; 27 | protected WebDriver driver; 28 | protected ExtentLogger extentLogger = new ExtentLogger(); 29 | protected static final Logger logger = LoggerFactory.getLogger(BasePageBrowser.class); 30 | public Eyes eye = ApplitoolEyesWeb.getEyesForPageObject(); 31 | private Map runTimeTestData = new HashMap(); 32 | private static final int DEFAULT_WAIT_TIMEOUT = 30; 33 | 34 | public BasePageBrowser() { 35 | driver = WebDriverFactory.getDriver(); 36 | fluentwait = getFluentWaitTimeout(); 37 | PageFactory.initElements(driver, this); 38 | runTimeTestData = RuntimeTestDataHolder.getRunTimeTestData(); 39 | } 40 | 41 | /** 42 | * Get FluentWait with DEFAULT_WAIT_TIMEOUT 43 | * 44 | * @return Wait 45 | */ 46 | 47 | protected Wait getFluentWaitTimeout() { 48 | return new FluentWait(driver).withTimeout(Duration.ofSeconds(DEFAULT_WAIT_TIMEOUT)) 49 | .pollingEvery(Duration.ofSeconds(1)).ignoring(NoSuchElementException.class); 50 | } 51 | 52 | /** 53 | * Get FluentWait with given TIMEOUT 54 | * 55 | * @param int timeOutInSeconds 56 | * @return Wait 57 | */ 58 | 59 | protected Wait getFluentWaitTimeout(int timeOutInSeconds) { 60 | return new FluentWait(driver).withTimeout(Duration.ofSeconds(timeOutInSeconds)) 61 | .pollingEvery(Duration.ofSeconds(1)).ignoring(NoSuchElementException.class); 62 | } 63 | 64 | public String getRunTimeTestData(String key) { 65 | return runTimeTestData.get(key); 66 | } 67 | 68 | public void setRunTimeTestData(String key, String value) { 69 | 70 | if (runTimeTestData.containsKey(key)) { 71 | logger.info("!!!!!!!!!! Duplicate Runtime Data Key inserstion found. Key " + key 72 | + " was already present in Map with value " + runTimeTestData.get(key) 73 | + ". Same key is being asked to insert again, so, overwriting it with new value " + value 74 | + ". Confirm if it is intended."); 75 | } 76 | runTimeTestData.put(key, value); 77 | } 78 | 79 | /** 80 | * Click on WebElement using JavaScriptExecutor 81 | * 82 | * @param WebElement element 83 | */ 84 | protected void clickOnElementUsingJS(WebElement element) { 85 | 86 | JavascriptExecutor jsExecutor = (JavascriptExecutor) driver; 87 | try { 88 | jsExecutor.executeScript("arguments[0].click();", element); 89 | } catch (Exception e) { 90 | logger.error("!!!!!!!ERROR Element is not clickable using JavascriptExecutor\n" + e.getMessage()); 91 | throw new TestException( 92 | String.format("The element is not clickable using JavascriptExecutor : [%s]", element)); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/base/BasePageMobile.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.base; 2 | 3 | import java.time.Duration; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.iqa.suite.commons.ExtentLogger; 8 | import org.iqa.suite.commons.applitool.ApplitoolEyesWeb; 9 | import org.iqa.test.test_data.RuntimeTestDataHolder; 10 | import org.iqa.test.webdriver_factory.WebDriverFactory; 11 | import org.openqa.selenium.NoSuchElementException; 12 | import org.openqa.selenium.WebDriver; 13 | import org.openqa.selenium.support.PageFactory; 14 | import org.openqa.selenium.support.ui.FluentWait; 15 | import org.openqa.selenium.support.ui.Wait; 16 | import org.slf4j.Logger; 17 | import org.slf4j.LoggerFactory; 18 | import org.testng.asserts.SoftAssert; 19 | 20 | import com.applitools.eyes.selenium.Eyes; 21 | 22 | import io.appium.java_client.AppiumDriver; 23 | import io.appium.java_client.pagefactory.AppiumFieldDecorator; 24 | 25 | public class BasePageMobile { 26 | 27 | protected SoftAssert softAssert; 28 | @SuppressWarnings("rawtypes") 29 | protected Wait fluentwait; 30 | @SuppressWarnings("rawtypes") 31 | protected AppiumDriver driver; 32 | protected ExtentLogger extentLogger = new ExtentLogger(); 33 | protected static final Logger logger = LoggerFactory.getLogger(BasePageBrowser.class); 34 | private static final int DEFAULT_WAIT_TIMEOUT = 30; 35 | protected Eyes eye = ApplitoolEyesWeb.getEyesForPageObject(); 36 | private Map runTimeTestData = new HashMap(); 37 | 38 | @SuppressWarnings("rawtypes") 39 | public BasePageMobile() { 40 | driver = (AppiumDriver) WebDriverFactory.getDriver(); 41 | fluentwait = getFluentWaitTimeout(); 42 | PageFactory.initElements(new AppiumFieldDecorator(driver), this); 43 | runTimeTestData = RuntimeTestDataHolder.getRunTimeTestData(); 44 | } 45 | 46 | /** 47 | * Get FluentWait with DEFAULT_WAIT_TIMEOUT 48 | * 49 | * @return Wait 50 | */ 51 | 52 | @SuppressWarnings("rawtypes") 53 | protected Wait getFluentWaitTimeout() { 54 | return new FluentWait((AppiumDriver) driver).withTimeout(Duration.ofSeconds(DEFAULT_WAIT_TIMEOUT)) 55 | .pollingEvery(Duration.ofSeconds(1)).ignoring(NoSuchElementException.class); 56 | } 57 | 58 | /** 59 | * Get FluentWait with given TIMEOUT 60 | * 61 | * @param int timeOutInSeconds 62 | * @return Wait 63 | */ 64 | 65 | protected Wait getFluentWaitTimeout(int timeOutInSeconds) { 66 | return new FluentWait(driver).withTimeout(Duration.ofSeconds(timeOutInSeconds)) 67 | .pollingEvery(Duration.ofSeconds(1)).ignoring(NoSuchElementException.class); 68 | } 69 | 70 | public String getRunTimeTestData(String key) { 71 | return runTimeTestData.get(key); 72 | } 73 | 74 | public void setRunTimeTestData(String key, String value) { 75 | 76 | if (runTimeTestData.containsKey(key)) { 77 | logger.info("!!!!!!!!!! Duplicate Runtime Data Key inserstion found. Key " + key 78 | + " was already present in Map with value " + runTimeTestData.get(key) 79 | + ". Same key is being asked to insert again, so, overwriting it with new value " + value 80 | + ". Confirm if it is intended."); 81 | } 82 | runTimeTestData.put(key, value); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/base/BaseTest.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.base; 2 | 3 | import org.iqa.suite.commons.PropertyHolder; 4 | import org.iqa.suite.commons.SeleniumUtils; 5 | import org.iqa.suite.commons.TestMetaData; 6 | import org.iqa.suite.commons.applitool.ApplitoolsEyesUtils; 7 | import org.iqa.suite.commons.listeners.TestNGMethodInvocationListener; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.testng.annotations.AfterSuite; 11 | import org.testng.annotations.BeforeSuite; 12 | import org.testng.annotations.Listeners; 13 | import org.testng.annotations.Test; 14 | 15 | import io.cucumber.testng.AbstractTestNGCucumberTests; 16 | import io.cucumber.testng.FeatureWrapper; 17 | import io.cucumber.testng.PickleWrapper; 18 | 19 | @Listeners(TestNGMethodInvocationListener.class) 20 | public class BaseTest extends AbstractTestNGCucumberTests { 21 | 22 | private static final Logger logger = LoggerFactory.getLogger(BaseTest.class); 23 | private static String AUT = null; 24 | 25 | @BeforeSuite 26 | public void beforeSuite() { 27 | 28 | logger.info("********* Loading Test suite config properties..."); 29 | PropertyHolder.loadFrameworkConfig(); 30 | PropertyHolder.loadApplitoolConfig(); 31 | PropertyHolder.loadGeneralConfig(); 32 | logger.info("********* Test suite config properties loaded successfully."); 33 | AUT = PropertyHolder.testSuiteConfigurationProperties.getProperty("AUT").toString(); 34 | logger.info("********* Application under test is : " + AUT); 35 | if (null == AUT) { 36 | logger.error( 37 | "!!!!!!!!!! AUT Property must be set in src/test/resources/properties/framework/FrameworkConfig.properties" 38 | + "\n Property name should be AUT and values should be one of {WEB, ANDROID,IOS, API_ONLY.}" 39 | + "\n AUT should be set as WEB/ANDROID/IOS if you want to execute Web/Mobile automation tests and it also allows execution of API tests." 40 | + "\n AUT should be set as API_ONLY if you want to execute only API tests}. Exiting..."); 41 | System.exit(-1); 42 | } 43 | 44 | if (!AUT.equalsIgnoreCase("API_ONLY")) { 45 | logger.info("********* Setting applitool eyes configs..."); 46 | ApplitoolsEyesUtils.setApplitoolEyeConfig(); 47 | logger.info("********* Applitools eyes configs set up done."); 48 | 49 | } 50 | } 51 | 52 | @Test(groups = "cucumber", description = "Runs Cucumber Scenarios", dataProvider = "scenarios") 53 | public void runScenario(PickleWrapper pickleWrapper, FeatureWrapper featureWrapper) { 54 | TestMetaData.setFeatureWrapper(featureWrapper); 55 | TestMetaData.setPickleWrapper(pickleWrapper); 56 | ApplitoolsEyesUtils.openApplitoolEye(); 57 | super.runScenario(pickleWrapper, featureWrapper); 58 | } 59 | 60 | @AfterSuite 61 | public void afterSuite() { 62 | // ***** Skipping applicationToolEyeWebGetAllTestResults as it is taking longer time for processing and causing execution pipeline to wait 63 | // 64 | // if (null != AUT && !AUT.equalsIgnoreCase("API_ONLY")) { 65 | // if (null != PropertyHolder.testSuiteConfigurationProperties.getProperty("EYE_ENABLE") && new Boolean( 66 | // PropertyHolder.testSuiteConfigurationProperties.getProperty("EYE_ENABLE").toString()) == true) { 67 | // String platform = SeleniumUtils.getOsFamilyName(PropertyHolder.testSuiteConfigurationProperties.getProperty("platform").toString()); 68 | // if (platform.equalsIgnoreCase("LINUX")) { 69 | // ApplitoolsEyesUtils.applicationToolEyeWebGetAllTestResults(); // Only for Web 70 | // } 71 | // } 72 | // } 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/runner/ParallelTestRunner.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.runner; 2 | 3 | import org.iqa.test.base.BaseTest; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.testng.annotations.DataProvider; 7 | 8 | public class ParallelTestRunner extends BaseTest { 9 | 10 | private static final Logger logger = LoggerFactory.getLogger(ParallelTestRunner.class); 11 | 12 | @Override 13 | @DataProvider(parallel = true) 14 | public Object[][] scenarios() { 15 | 16 | //Call to scenarios method of AbstractTestNGCucumberTests 17 | return super.scenarios(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/runner/SequentialTestRunner.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.runner; 2 | 3 | import org.iqa.test.base.BaseTest; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.testng.annotations.DataProvider; 7 | 8 | public class SequentialTestRunner extends BaseTest { 9 | private static final Logger logger = LoggerFactory.getLogger(SequentialTestRunner.class); 10 | 11 | @Override 12 | @DataProvider(parallel = false) 13 | public Object[][] scenarios() { 14 | 15 | //Call to scenarios method of AbstractTestNGCucumberTests 16 | return super.scenarios(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/test_data/PersonData.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.test_data; 2 | 3 | public class PersonData { 4 | 5 | public enum lastName 6 | { 7 | Smith,Johnson,Williams,Brown,Jones,Miller,Davis,Garcia,Rodriguez,Wilson,Martinez,Anderson,Taylor,Thomas,Hernandez,Moore,Martin,Jackson,Thompson,White,Lopez,Lee,Gonzalez,Harris,Clark,Lewis,Robinson,Walker,Perez,Hall,Young,Allen,Sanchez,Wright,King,Scott,Green,Baker,Adams,Nelson,Hill,Ramirez,Campbell,Mitchell,Roberts,Carter,Phillips,Evans,Turner,Torres,Parker,Collins,Edwards,Stewart,Flores,Morris,Nguyen,Murphy,Rivera,Cook,Rogers,Morgan,Peterson,Cooper,Reed,Bailey,Bell,Gomez,Kelly,Howard,Ward,Cox,Diaz,Richardson,Wood,Watson,Brooks,Bennett,Gray,James,Reyes,Cruz,Hughes,Price,Myers,Long,Foster,Sanders,Ross,Morales,Powell,Sullivan,Russell,Ortiz,Jenkins,Gutierrez,Perry,Butler,Barnes,Fisher,Henderson,Coleman,Simmons,Patterson,Jordan,Reynolds,Hamilton,Graham,Kim,Gonzales,Alexander,Ramos,Wallace,Griffin,West,Cole,Hayes,Chavez,Gibson,Bryant,Ellis,Stevens,Murray,Ford,Marshall,Owens,Mcdonald,Harrison,Ruiz,Kennedy,Wells,Alvarez,Woods,Mendoza,Castillo,Olson,Webb,Washington,Tucker,Freeman,Burns,Henry,Vasquez,Snyder,Simpson,Crawford,Jimenez,Porter,Mason,Shaw,Gordon,Wagner,Hunter,Romero,Hicks,Dixon,Hunt,Palmer,Robertson,Black,Holmes,Stone,Meyer,Boyd,Mills,Warren,Fox,Rose,Rice,Moreno,Schmidt,Patel,Ferguson,Nichols,Herrera,Medina,Ryan,Fernandez,Weaver,Daniels,Stephens,Gardner,Payne,Kelley,Dunn,Pierce,Arnold,Tran,Spencer,Peters,Hawkins,Grant,Hansen,Castro,Hoffman,Hart,Elliott,Cunningham,Knight,Bradley,Carroll,Hudson,Duncan,Armstrong,Berry,Andrews,Johnston,Ray,Lane,Riley,Carpenter,Perkins,Aguilar,Silva,Richards,Willis,Matthews,Chapman,Lawrence,Garza,Vargas,Watkins,Wheeler,Larson,Carlson,Harper,George,Greene,Burke,Guzman,Morrison,Munoz,Jacobs,Obrien,Lawson,Franklin,Lynch,Bishop,Carr,Salazar,Austin,Mendez,Gilbert,Jensen,Williamson,Montgomery,Harvey,Oliver,Howell,Dean,Hanson,Weber,Garrett,Sims,Burton,Fuller,Soto,Mccoy,Welch,Chen,Schultz,Walters,Reid,Fields,Walsh,Little,Fowler,Bowman,Davidson,May,Day,Schneider,Newman,Brewer,Lucas,Holland,Wong,Banks,Santos,Curtis,Pearson,Delgado,Valdez,Pena,Rios,Douglas,Sandoval,Barrett,Hopkins,Keller,Guerrero,Stanley,Bates,Alvarado,Beck,Ortega,Wade,Estrada,Contreras,Barnett,Caldwell,Santiago,Lambert,Powers,Chambers,Nunez,Craig,Leonard,Lowe,Rhodes,Byrd,Gregory,Shelton,Frazier,Becker,Maldonado,Fleming,Vega,Sutton,Cohen,Jennings,Parks,Mcdaniel,Watts,Barker,Norris,Vaughn,Vazquez,Holt,Schwartz,Steele,Benson,Neal,Dominguez,Horton,Terry,Wolfe,Hale,Lyons,Graves,Haynes,Miles,Park,Warner,Padilla,Bush,Thornton,Mccarthy,Mann,Zimmerman,Erickson,Fletcher,Mckinney,Page,Dawson,Joseph,Marquez,Reeves,Klein,Espinoza,Baldwin,Moran,Love,Robbins,Higgins,Ball,Cortez,Le,Griffith,Bowen,Sharp,Cummings,Ramsey,Hardy,Swanson,Barber,Acosta,Luna,Chandler,Blair,Daniel,Cross,Simon,Dennis,Oconnor,Quinn,Gross,Navarro,Moss,Fitzgerald,Doyle,Mclaughlin,Rojas,Rodgers,Stevenson,Singh,Yang,Figueroa,Harmon,Newton,Paul,Manning,Garner,Mcgee,Reese,Francis,Burgess,Adkins,Goodman,Curry,Brady,Christensen,Potter,Walton,Goodwin,Mullins,Molina,Webster,Fischer,Campos,Avila,Sherman,Todd,Chang,Blake,Malone,Wolf,Hodges,Juarez,Gill,Farmer,Hines,Gallagher,Duran,Hubbard,Cannon,Miranda,Wang,Saunders,Tate,Mack,Hammond,Carrillo,Townsend,Wise,Ingram,Barton,Mejia,Ayala,Schroeder,Hampton,Rowe,Parsons,Frank,Waters,Strickland,Osborne,Maxwell,Chan,Deleon,Norman,Harrington,Casey,Patton,Logan,Bowers,Mueller,Glover,Floyd,Hartman,Buchanan,Cobb,French,Kramer,Mccormick,Clarke,Tyler,Gibbs,Moody,Conner,Sparks,Mcguire,Leon,Bauer,Norton,Pope,Flynn,Hogan,Robles,Salinas,Yates,Lindsey,Lloyd,Marsh,Mcbride,Owen,Solis,Pham,Lang,Pratt,Lara,Brock,Ballard,Trujillo,Shaffer,Drake,Roman,Aguirre,Morton,Stokes,Lamb,Pacheco,Patrick,Cochran,Shepherd,Cain,Burnett,Hess,Li,Cervantes,Olsen,Briggs,Ochoa,Cabrera,Velasquez,Montoya,Roth,Meyers,Cardenas,Fuentes,Weiss,Wilkins,Hoover,Nicholson,Underwood,Short,Carson,Morrow,Colon,Holloway,Summers,Bryan,Petersen,Mckenzie,Serrano,Wilcox,Carey,Clayton,Poole,Calderon,Gallegos,Greer,Rivas,Guerra,Decker,Collier,Wall,Whitaker,Bass,Flowers,Davenport,Conley,Houston,Huff,Copeland,Hood,Monroe,Massey,Roberson,Combs,Franco,Larsen,Pittman,Randall,Skinner,Wilkinson,Kirby,Cameron,Bridges,Anthony,Richard,Kirk,Bruce,Singleton,Mathis,Bradford,Boone,Abbott,Charles,Allison,Sweeney,Atkinson,Horn,Jefferson,Rosales,York,Christian,Phelps,Farrell,Castaneda,Nash,Dickerson,Bond,Wyatt,Foley,Chase,Gates,Vincent,Mathews,Hodge,Garrison,Trevino,Villarreal,Heath,Dalton,Valencia,Callahan,Hensley,Atkins,Huffman,Roy,Boyer,Shields,Lin,Hancock,Grimes,Glenn,Cline,Delacruz,Camacho,Dillon,Parrish,Oneill,Melton,Booth,Kane,Berg,Harrell,Pitts,Savage,Wiggins,Brennan,Salas,Marks,Russo,Sawyer,Baxter,Golden,Hutchinson,Liu,Walter,Mcdowell,Wiley,Rich,Humphrey,Johns,Koch,Suarez,Hobbs,Beard,Gilmore,Ibarra,Keith,Macias,Khan,Andrade,Ware,Stephenson,Henson,Wilkerson,Dyer,Mcclure,Blackwell,Mercado,Tanner,Eaton,Clay,Barron,Beasley,Oneal,Small,Preston,Wu,Zamora,Macdonald,Vance,Snow,Mcclain,Stafford,Orozco,Barry,English,Shannon,Kline,Jacobson,Woodard,Huang,Kemp,Mosley,Prince,Merritt,Hurst,Villanueva,Roach,Nolan,Lam,Yoder,Mccullough,Lester,Santana,Valenzuela,Winters,Barrera,Orr,Leach,Berger,Mckee,Strong,Conway,Stein,Whitehead,Bullock,Escobar,Knox,Meadows,Solomon,Velez,Odonnell,Kerr,Stout,Blankenship,Browning,Kent,Lozano,Bartlett,Pruitt,Buck,Barr,Gaines,Durham,Gentry,Mcintyre,Sloan,Rocha,Melendez,Herman,Sexton,Moon,Hendricks,Rangel,Stark,Lowery,Hardin,Hull,Sellers,Ellison,Calhoun,Gillespie,Mora,Knapp,Mccall,Morse,Dorsey,Weeks,Nielsen,Livingston,Leblanc,Mclean,Bradshaw,Glass,Middleton,Buckley,Schaefer,Frost,Howe,House,Mcintosh,Ho,Pennington,Reilly,Hebert,Mcfarland,Hickman,Noble,Spears,Conrad,Arias,Galvan,Velazquez,Huynh,Frederick,Randolph,Cantu,Fitzpatrick,Mahoney,Peck,Villa,Michael,Donovan,Mcconnell,Walls,Boyle,Mayer,Zuniga,Giles,Pineda,Pace,Hurley,Mays,Mcmillan,Crosby,Ayers,Case,Bentley,Shepard,Everett,Pugh,David,Mcmahon,Dunlap,Bender,Hahn,Harding,Acevedo,Raymond,Blackburn,Duffy,Landry,Dougherty,Bautista,Shah,Potts,Arroyo,Valentine,Meza,Gould,Vaughan,Fry,Rush,Avery,Herring,Dodson,Clements,Sampson,Tapia,Bean,Lynn,Crane,Farley,Cisneros,Benton,Ashley,Mckay,Finley,Best,Blevins,Friedman,Moses,Sosa,Blanchard,Huber,Frye,Krueger,Bernard,Rosario,Rubio,Mullen,Benjamin,Haley,Chung,Moyer,Choi,Horne,Yu,Woodward,Ali,Nixon,Hayden,Rivers,Estes,Mccarty,Richmond,Stuart,Maynard,Brandt,Oconnell,Hanna,Sanford,Sheppard,Church,Burch,Levy,Rasmussen,Coffey,Ponce,Faulkner,Donaldson,Schmitt,Novak,Costa,Montes,Booker,Cordova,Waller,Arellano,Maddox,Mata,Bonilla,Stanton,Compton,Kaufman,Dudley,Mcpherson,Beltran,Dickson,Mccann,Villegas,Proctor,Hester,Cantrell,Daugherty,Cherry,Bray,Davila,Rowland,Madden,Levine,Spence,Good,Irwin,Werner,Krause,Petty,Whitney,Baird,Hooper,Pollard,Zavala,Jarvis,Holden,Haas,Hendrix,Mcgrath,Bird,Lucero,Terrell,Riggs,Joyce,Mercer,Rollins,Galloway,Duke,Odom,Andersen,Downs,Hatfield,Benitez,Archer,Huerta,Travis,Mcneil,Hinton,Zhang,Hays,Mayo,Fritz,Branch,Mooney,Ewing,Ritter,Esparza,Frey,Braun,Gay,Riddle,Haney,Kaiser,Holder,Chaney,Mcknight,Gamble,Vang,Cooley,Carney,Cowan,Forbes,Ferrell,Davies,Barajas,Shea,Osborn,Bright,Cuevas,Bolton,Murillo,Lutz,Duarte,Kidd,Key,Cooke 8 | } 9 | 10 | public enum firstNameMale 11 | { 12 | James,John,Robert,Michael,William,David,Richard,Charles,Joseph,Thomas,Christopher,Daniel,Paul,Mark,Donald,George,Kenneth,Steven,Edward,Brian,Ronald,Anthony,Kevin,Jason,Matthew,Gary,Timothy,Jose,Larry,Jeffrey,Frank,Scott,Eric,Stephen,Andrew,Raymond,Gregory,Joshua,Jerry,Dennis,Walter,Patrick,Peter,Harold,Douglas,Henry,Carl,Arthur,Ryan,Roger,Joe,Juan,Jack,Albert,Jonathan,Justin,Terry,Gerald,Keith,Samuel,Willie,Ralph,Lawrence,Nicholas,Roy,Benjamin,Bruce,Brandon,Adam,Harry,Fred,Wayne,Billy,Steve,Louis,Jeremy,Aaron,Randy,Howard,Eugene,Carlos,Russell,Bobby,Victor,Martin,Ernest,Phillip,Todd,Jesse,Craig,Alan,Shawn,Clarence,Sean,Philip,Chris,Johnny,Earl,Jimmy,Antonio,Danny,Bryan,Tony,Luis,Mike,Stanley,Leonard,Nathan,Dale,Manuel,Rodney,Curtis,Norman,Allen,Marvin,Vincent,Glenn,Jeffery,Travis,Jeff,Chad,Jacob,Lee,Melvin,Alfred,Kyle,Francis,Bradley,Jesus,Herbert,Frederick,Ray,Joel,Edwin,Don,Eddie,Ricky,Troy,Randall,Barry,Alexander,Bernard,Mario,Leroy,Francisco,Marcus,Micheal,Theodore,Clifford,Miguel,Oscar,Jay,Jim,Tom,Calvin,Alex,Jon,Ronnie,Bill,Lloyd,Tommy,Leon,Derek,Warren,Darrell,Jerome,Floyd,Leo,Alvin,Tim,Wesley,Gordon,Dean,Greg,Jorge,Dustin,Pedro,Derrick,Dan,Lewis,Zachary,Corey,Herman,Maurice,Vernon,Roberto,Clyde,Glen,Hector,Shane,Ricardo,Sam,Rick,Lester,Brent,Ramon,Charlie,Tyler,Gilbert,Gene,Marc,Reginald,Ruben,Brett,Angel,Nathaniel,Rafael,Leslie,Edgar,Milton,Raul,Ben,Chester,Cecil,Duane,Franklin,Andre,Elmer,Brad,Gabriel,Ron,Mitchell,Roland,Arnold,Harvey,Jared,Adrian,Karl,Cory,Claude,Erik,Darryl,Jamie,Neil,Jessie,Christian,Javier,Fernando,Clinton,Ted,Mathew,Tyrone,Darren,Lonnie,Lance,Cody,Julio,Kelly,Kurt,Allan,Nelson,Guy,Clayton,Hugh,Max,Dwayne,Dwight,Armando,Felix,Jimmie,Everett,Jordan,Ian,Wallace,Ken,Bob,Jaime,Casey,Alfredo,Alberto,Dave,Ivan,Johnnie,Sidney,Byron,Julian,Isaac,Morris,Clifton,Willard,Daryl,Ross,Virgil,Andy,Marshall,Salvador,Perry,Kirk,Sergio,Marion,Tracy,Seth,Kent,Terrance,Rene,Eduardo,Terrence,Enrique,Freddie,Wade 13 | } 14 | 15 | public enum firstNameFemale 16 | { 17 | Mary,Patricia,Linda,Barbara,Elizabeth,Jennifer,Maria,Susan,Margaret,Dorothy,Lisa,Nancy,Karen,Betty,Helen,Sandra,Donna,Carol,Ruth,Sharon,Michelle,Laura,Sarah,Kimberly,Deborah,Jessica,Shirley,Cynthia,Angela,Melissa,Brenda,Amy,Anna,Rebecca,Virginia,Kathleen,Pamela,Martha,Debra,Amanda,Stephanie,Carolyn,Christine,Marie,Janet,Catherine,Frances,Ann,Joyce,Diane,Alice,Julie,Heather,Teresa,Doris,Gloria,Evelyn,Jean,Cheryl,Mildred,Katherine,Joan,Ashley,Judith,Rose,Janice,Kelly,Nicole,Judy,Christina,Kathy,Theresa,Beverly,Denise,Tammy,Irene,Jane,Lori,Rachel,Marilyn,Andrea,Kathryn,Louise,Sara,Anne,Jacqueline,Wanda,Bonnie,Julia,Ruby,Lois,Tina,Phyllis,Norma,Paula,Diana,Annie,Lillian,Emily,Robin,Peggy,Crystal,Gladys,Rita,Dawn,Connie,Florence,Tracy,Edna,Tiffany,Carmen,Rosa,Cindy,Grace,Wendy,Victoria,Edith,Kim,Sherry,Sylvia,Josephine,Thelma,Shannon,Sheila,Ethel,Ellen,Elaine,Marjorie,Carrie,Charlotte,Monica,Esther,Pauline,Emma,Juanita,Anita,Rhonda,Hazel,Amber,Eva,Debbie,April,Leslie,Clara,Lucille,Jamie,Joanne,Eleanor,Valerie,Danielle,Megan,Alicia,Suzanne,Michele,Gail,Bertha,Darlene,Veronica,Jill,Erin,Geraldine,Lauren,Cathy,Joann,Lorraine,Lynn,Sally,Regina,Erica,Beatrice,Dolores,Bernice,Audrey,Yvonne,Annette,June,Samantha,Marion,Dana,Stacy,Ana,Renee,Ida,Vivian,Roberta,Holly,Brittany,Melanie,Loretta,Yolanda,Jeanette,Laurie,Katie,Kristen,Vanessa,Alma,Sue,Elsie,Beth,Jeanne,Vicki,Carla,Tara,Rosemary,Eileen,Terri,Gertrude,Lucy,Tonya,Ella,Stacey,Wilma,Gina,Kristin,Jessie,Natalie,Agnes,Vera,Willie,Charlene,Bessie,Delores,Melinda,Pearl,Arlene,Maureen,Colleen,Allison,Tamara,Joy,Georgia,Constance,Lillie,Claudia,Jackie,Marcia,Tanya,Nellie,Minnie,Marlene,Heidi,Glenda,Lydia,Viola,Courtney,Marian,Stella,Caroline,Dora,Jo,Vickie,Mattie,Terry,Maxine,Irma,Mabel,Marsha,Myrtle,Lena,Christy,Deanna,Patsy,Hilda,Gwendolyn,Jennie,Nora,Margie,Nina,Cassandra,Leah,Penny,Kay,Priscilla,Naomi,Carole,Brandy,Olga,Billie,Dianne,Tracey,Leona,Jenny,Felicia,Sonia,Miriam,Velma,Becky,Bobbie,Violet,Kristina,Toni,Misty,Mae,Shelly,Daisy,Ramona,Sherri,Erika,Katrina,Claire,Lindsey,Lindsay,Geneva,Guadalupe,Belinda,Margarita,Sheryl,Cora,Faye,Ada,Natasha,Sabrina,Isabel,Marguerite,Hattie,Harriet,Molly,Cecilia,Kristi,Brandi,Blanche,Sandy,Rosie,Joanna,Iris,Eunice,Angie,Inez,Lynda,Madeline,Amelia,Alberta,Genevieve,Monique,Jodi,Janie,Maggie,Kayla,Sonya,Jan,Lee,Kristine,Candace,Fannie,Maryann,Opal,Alison,Yvette,Melody,Luz,Susie,Olivia,Flora,Shelley,Kristy,Mamie,Lula,Lola,Verna,Beulah,Antoinette,Candice,Juana,Jeannette,Pam,Kelli,Hannah,Whitney,Bridget,Karla,Celia,Latoya,Patty,Shelia,Gayle,Della,Vicky,Lynne,Sheri,Marianne,Kara,Jacquelyn,Erma,Blanca,Myra,Leticia,Pat,Krista,Roxanne,Angelica,Johnnie,Robyn,Francis,Adrienne,Rosalie,Alexandra,Brooke,Bethany,Sadie,Bernadette,Traci,Jody,Kendra,Jasmine,Nichole,Rachael,Chelsea,Mable,Ernestine,Muriel,Marcella,Elena,Krystal,Angelina,Nadine,Kari,Estelle,Dianna,Paulette,Lora,Mona,Doreen,Rosemarie,Angel,Desiree,Antonia,Hope,Ginger,Janis,Betsy,Christie,Freda,Mercedes,Meredith,Lynette,Teri,Cristina,Eula,Leigh,Meghan,Sophia,Eloise,Rochelle,Gretchen,Cecelia,Raquel,Henrietta,Alyssa,Jana,Kelley,Gwen,Kerry,Jenna,Tricia,Laverne,Olive,Alexis,Tasha,Silvia,Elvira,Casey,Delia,Sophie,Kate,Patti,Lorena,Kellie,Sonja,Lila,Lana,Darla,May,Mindy,Essie,Mandy,Lorene,Elsa,Josefina,Jeannie,Miranda,Dixie,Lucia,Marta,Faith,Lela,Johanna,Shari,Camille,Tami,Shawna,Elisa,Ebony,Melba,Ora,Nettie,Tabitha,Ollie,Jaime,Winifred,Kristie,Marina,Alisha,Aimee,Rena,Myrna,Marla,Tammie,Latasha,Bonita,Patrice,Ronda,Sherrie,Addie,Francine,Deloris,Stacie,Adriana,Cheri,Shelby,Abigail,Celeste,Jewel,Cara,Adele,Rebekah,Lucinda,Dorthy,Chris,Effie,Trina,Reba,Shawn,Sallie,Aurora,Lenora,Etta,Lottie,Kerri,Trisha,Nikki,Estella,Francisca,Josie,Tracie,Marissa,Karin,Brittney,Janelle,Lourdes,Laurel,Helene,Fern,Elva,Corinne,Kelsey,Ina,Bettie,Elisabeth,Aida,Caitlin,Ingrid,Iva,Eugenia,Christa,Goldie,Cassie,Maude,Jenifer,Therese,Frankie,Dena,Lorna,Janette,Latonya,Candy,Morgan,Consuelo,Tamika,Rosetta,Debora,Cherie,Polly,Dina,Jewell,Fay,Jillian,Dorothea,Nell,Trudy,Esperanza,Patrica,Kimberley,Shanna,Helena,Carolina,Cleo,Stefanie,Rosario,Ola,Janine,Mollie,Lupe,Alisa,Lou,Maribel,Susanne,Bette,Susana,Elise,Cecile,Isabelle,Lesley,Jocelyn,Paige,Joni,Rachelle,Leola,Daphne,Alta,Ester,Petra,Graciela,Imogene,Jolene,Keisha,Lacey,Glenna,Gabriela,Keri,Ursula,Lizzie,Kirsten,Shana,Adeline,Mayra,Jayne,Jaclyn,Gracie,Sondra,Carmela,Marisa,Rosalind,Charity,Tonia,Beatriz,Marisol,Clarice,Jeanine,Sheena,Angeline,Frieda,Lily,Robbie,Shauna,Millie,Claudette,Cathleen,Angelia,Gabrielle,Autumn,Katharine,Summer,Jodie,Staci,Lea,Christi,Jimmie,Justine,Elma,Luella,Margret,Dominique,Socorro,Rene,Martina,Margo,Mavis,Callie,Bobbi,Maritza,Lucile,Leanne,Jeannine,Deana,Aileen,Lorie,Ladonna,Willa,Manuela,Gale,Selma,Dolly,Sybil,Abby,Lara,Dale,Ivy,Dee,Winnie,Marcy,Luisa,Jeri,Magdalena,Ofelia,Meagan,Audra,Matilda,Leila,Cornelia,Bianca,Simone,Bettye,Randi,Virgie,Latisha,Barbra,Georgina,Eliza,Leann,Bridgette,Rhoda,Haley,Adela,Nola,Bernadine,Flossie,Ila,Greta,Ruthie,Nelda,Minerva,Lilly,Terrie,Letha,Hilary,Estela,Valarie,Brianna,Rosalyn,Earline,Catalina,Ava,Mia,Clarissa,Lidia,Corrine,Alexandria,Concepcion,Tia,Sharron,Rae,Dona,Ericka,Jami,Elnora,Chandra,Lenore,Neva,Marylou,Melisa,Tabatha,Serena,Avis,Allie,Sofia,Jeanie,Odessa,Nannie,Harriett,Loraine,Penelope,Milagros,Emilia,Benita,Allyson,Ashlee,Tania,Tommie,Esmeralda,Karina,Eve,Pearlie,Zelma,Malinda,Noreen,Tameka,Saundra,Hillary,Amie,Althea,Rosalinda,Jordan,Lilia,Alana,Gay,Clare,Alejandra,Elinor,Michael,Lorrie,Jerri,Darcy,Earnestine,Carmella,Taylor,Noemi,Marcie,Liza,Annabelle,Louisa,Earlene,Mallory,Carlene,Nita,Selena,Tanisha,Katy,Julianne,John,Lakisha,Edwina,Maricela,Margery,Kenya,Dollie,Roxie,Roslyn,Kathrine,Nanette,Charmaine,Lavonne,Ilene,Kris,Tammi,Suzette,Corine,Kaye,Jerry,Merle,Chrystal,Lina,Deanne,Lilian,Juliana,Aline,Luann,Kasey,Maryanne,Evangeline,Colette,Melva,Lawanda,Yesenia,Nadia,Madge,Kathie,Eddie,Ophelia,Valeria,Nona,Mitzi,Mari,Georgette,Claudine,Fran,Alissa,Roseann,Lakeisha,Susanna,Reva,Deidre,Chasity,Sheree,Carly,James,Elvia,Alyce,Deirdre,Gena,Briana,Araceli,Katelyn,Rosanne,Wendi,Tessa,Berta,Marva,Imelda,Marietta,Marci,Leonor,Arline,Sasha,Madelyn,Janna,Juliette,Deena,Aurelia,Josefa,Augusta,Liliana,Young,Christian,Lessie,Amalia,Savannah,Anastasia,Vilma,Natalia,Rosella,Lynnette,Corina,Alfreda,Leanna,Carey,Amparo,Coleen,Tamra,Aisha,Wilda,Karyn,Cherry,Queen,Maura,Mai,Evangelina,Rosanna,Hallie,Erna,Enid,Mariana,Lacy,Juliet,Jacklyn,Freida,Madeleine,Mara,Hester,Cathryn,Lelia,Casandra,Bridgett,Angelita,Jannie,Dionne,Annmarie,Katina,Beryl,Phoebe,Millicent,Katheryn,Diann,Carissa,Maryellen,Liz,Lauri,Helga,Gilda,Adrian,Rhea,Marquita,Hollie,Tisha,Tamera,Angelique,Francesca,Britney,Kaitlin,Lolita,Florine,Rowena,Reyna,Twila,Fanny,Janell,Ines,Concetta,Bertie,Alba,Brigitte,Alyson,Vonda,Pansy,Elba,Noelle,Letitia,Kitty,Deann,Brandie,Louella,Leta,Felecia,Sharlene,Lesa,Beverley,Robert,Isabella,Herminia,Terra,Celina 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/test_data/RandomGenerator.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.test_data; 2 | 3 | import org.apache.commons.lang3.RandomStringUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | public class RandomGenerator { 8 | 9 | private static final Logger logger = LoggerFactory.getLogger(RandomGenerator.class); 10 | 11 | /** 12 | * Generate random string of given length 13 | * 14 | * @param int numberOfChars 15 | * @return String randomValue 16 | */ 17 | public String generateRandomString(int numberOfChars) { 18 | String randomValue = RandomStringUtils.randomAlphabetic(numberOfChars); 19 | logger.info("*****RandomGenerator random string -" + randomValue); 20 | return randomValue; 21 | } 22 | 23 | /** 24 | * Generate random string of given length with user provided prefix 25 | * 26 | * @param int numberOfChars 27 | * @return String randomValue 28 | */ 29 | public String generateRandomStringWithPrefix(String prefix, int numberOfChars) { 30 | String randomValue = prefix + RandomStringUtils.randomAlphabetic(numberOfChars); 31 | logger.info("*****RandomGenerator random string with prefix -" + randomValue); 32 | return randomValue; 33 | } 34 | 35 | /** 36 | * Generate random number of given length 37 | * 38 | * @param int numberOfDigit 39 | * @return String randomValue 40 | */ 41 | public String generateRandomNumber(int numberOfDigit) { 42 | String randomValue = RandomStringUtils.randomNumeric(numberOfDigit); 43 | logger.info("*****RandomGenerator random number -" + randomValue); 44 | return randomValue; 45 | } 46 | 47 | /** 48 | * Generate random number with user provided prefix 49 | * 50 | * @param int numberOfDigit 51 | * @return String randomValue 52 | */ 53 | public String generateRandomNumberWithPrefix(String prefix, int numberOfDigit) { 54 | String randomValue = RandomStringUtils.randomNumeric(numberOfDigit); 55 | logger.info("*****RandomGenerator random number with prefix -" + randomValue); 56 | return randomValue; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/test_data/RuntimeTestDataHolder.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.test_data; 2 | 3 | import java.util.HashMap; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class RuntimeTestDataHolder { 9 | 10 | private static final Logger logger = LoggerFactory.getLogger(RuntimeTestDataHolder.class); 11 | private static ThreadLocal> testDataHolder = new ThreadLocal>(); 12 | 13 | public static HashMap getRunTimeTestData() { 14 | return testDataHolder.get(); 15 | } 16 | 17 | public static void setRunTimeTestData(HashMap dataMap) { 18 | testDataHolder.set(dataMap); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/webdriver_factory/CapabilityFactory.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.webdriver_factory; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.Properties; 8 | import org.iqa.suite.commons.PropertyHolder; 9 | import org.openqa.selenium.remote.DesiredCapabilities; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | public class CapabilityFactory { 14 | private static final Logger logger = LoggerFactory.getLogger(CapabilityFactory.class); 15 | private static DesiredCapabilities desiredCapabilities = new DesiredCapabilities(); 16 | 17 | static { 18 | String AUT = PropertyHolder.testSuiteConfigurationProperties.getProperty("AUT").toString(); 19 | logger.debug("*********** Static block start. AUT - " + AUT); 20 | switch (AUT) { 21 | case "ANDROID": 22 | logger.debug("*********** ANDROID IN"); 23 | fillCapabilities(getProperties("AndroidCapabilities.properties")); 24 | logger.debug("*********** ANDROIF OUT"); 25 | break; 26 | case "IOS": 27 | logger.debug("*********** IOS IN"); 28 | fillCapabilities(getProperties("iOSCapabilities.properties")); 29 | logger.debug("*********** IOS OUT"); 30 | break; 31 | default: 32 | logger.debug("*********** BROWSER IN"); 33 | fillCapabilities(getProperties("BrowserCapabilities.properties")); 34 | logger.debug("*********** BROWSER OUT"); 35 | break; 36 | } 37 | logger.debug("*********** Static block end"); 38 | logger.info("********************************************************************"); 39 | logger.info("******************* DesiredCapabilities set as: ********************"); 40 | desiredCapabilities.asMap().forEach((key, value) -> logger.info(key + " - " + value)); 41 | logger.info("********************************************************************"); 42 | } 43 | 44 | public static DesiredCapabilities getDesiredCapabilities() { 45 | 46 | if (null == desiredCapabilities) { 47 | logger.error("!!!!!!!!!!! Desired capability found null"); 48 | } 49 | return desiredCapabilities; 50 | } 51 | 52 | private static void fillCapabilities(Properties properties) { 53 | logger.debug("fillCapabilities IN - " + properties.toString()); 54 | // Consider capablities present in testSuiteConfiguration else use from property 55 | // file. This is useful to pass browserName or version or package from 56 | // Environment or as Parameter 57 | properties.forEach((k, v) -> desiredCapabilities.setCapability(k.toString(), 58 | null != PropertyHolder.testSuiteConfigurationProperties.getProperty(k.toString()) 59 | ? PropertyHolder.testSuiteConfigurationProperties.getProperty(k.toString()) 60 | : v.toString())); 61 | 62 | logger.debug("fillCapabilities OUT - " + properties.toString()); 63 | } 64 | 65 | private static Properties getProperties(String propertyFileName) { 66 | logger.debug("getProperties IN - " + propertyFileName); 67 | InputStream input; 68 | Properties properties = new Properties(); 69 | try { 70 | input = new FileInputStream("src/test/resources/properties/capabilities/" + propertyFileName); 71 | properties = new Properties(); 72 | properties.load(input); 73 | } catch (FileNotFoundException e) { 74 | logger.error("!!!!! Unable to laoad property file at location src/test/resources/properties/capabilities/" 75 | + propertyFileName); 76 | e.printStackTrace(); 77 | System.exit(-1); 78 | } catch (IOException e) { 79 | logger.error("!!!!! Unable to laoad property file at location src/test/resources/properties/capabilities/" 80 | + propertyFileName + " \n Please check content of property file and try again."); 81 | e.printStackTrace(); 82 | System.exit(-1); 83 | } 84 | logger.debug("getProperties OUT - " + propertyFileName); 85 | // Loading Capabilities properties into testSuiteConfigurationProperties for 86 | // further usage 87 | loadPropertiesIntoTestConfig(properties); 88 | return properties; 89 | } 90 | 91 | private static void loadPropertiesIntoTestConfig(Properties properties) { 92 | 93 | properties.forEach((k, v) -> PropertyHolder.testSuiteConfigurationProperties.put(k.toString(), 94 | null != PropertyHolder.testSuiteConfigurationProperties.getProperty(k.toString()) 95 | ? PropertyHolder.testSuiteConfigurationProperties.getProperty(k.toString()) 96 | : v.toString())); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/webdriver_factory/WebDriverFactory.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.webdriver_factory; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | 5 | public class WebDriverFactory { 6 | 7 | private static ThreadLocal webDriver= new ThreadLocal(); 8 | 9 | synchronized public static WebDriver getDriver(){ 10 | return webDriver.get(); 11 | } 12 | synchronized public static void setDriver(WebDriver dr){ 13 | webDriver.set(dr); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/java/org/iqa/test/webdriver_factory/WebDriverManager.java: -------------------------------------------------------------------------------- 1 | package org.iqa.test.webdriver_factory; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | import org.iqa.suite.commons.PropertyHolder; 6 | import org.iqa.suite.commons.SeleniumUtils; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.WebElement; 9 | import org.openqa.selenium.chrome.ChromeDriver; 10 | import org.openqa.selenium.firefox.FirefoxDriver; 11 | import org.openqa.selenium.ie.InternetExplorerDriver; 12 | import org.openqa.selenium.remote.RemoteWebDriver; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import io.appium.java_client.android.AndroidDriver; 16 | import io.appium.java_client.ios.IOSDriver; 17 | 18 | public class WebDriverManager { 19 | private static final Logger logger = LoggerFactory.getLogger(WebDriverManager.class); 20 | 21 | synchronized public static WebDriver CreateInstance() throws MalformedURLException { 22 | WebDriver dr = null; 23 | logger.info("********* Before Webdriver object creation"); 24 | try { 25 | if (PropertyHolder.testSuiteConfigurationProperties.getProperty("DRIVER").toString().contains("BROWSER")) { 26 | System.setProperty(PropertyHolder.testSuiteConfigurationProperties.getProperty("DRIVER_PROPERTY_NAME"), 27 | PropertyHolder.testSuiteConfigurationProperties.getProperty("DRIVER_EXECUTABLE_PATH")); 28 | if (PropertyHolder.testSuiteConfigurationProperties.getProperty("browser").toString() 29 | .contains("chrome")) 30 | dr = new ChromeDriver(); 31 | else if (PropertyHolder.testSuiteConfigurationProperties.getProperty("browser").toString() 32 | .contains("firefox")) 33 | dr = new FirefoxDriver(); 34 | else if (PropertyHolder.testSuiteConfigurationProperties.getProperty("browser").toString() 35 | .contains("ie")) 36 | dr = new InternetExplorerDriver(); 37 | else { 38 | logger.error("!!!!!!!!!!Error - Browser Name is not found. Exiting..."); 39 | System.exit(-1); 40 | } 41 | } else if (PropertyHolder.testSuiteConfigurationProperties.getProperty("DRIVER").toString() 42 | .contains("REMOTE")) { 43 | String AUT = PropertyHolder.testSuiteConfigurationProperties.getProperty("AUT").toString(); 44 | if (AUT.equals("ANDROID")) 45 | dr = new AndroidDriver( 46 | new URL(PropertyHolder.testSuiteConfigurationProperties.getProperty("hubUrl").toString()), 47 | CapabilityFactory.getDesiredCapabilities()); 48 | else if (AUT.equals("IOS")) 49 | dr = new IOSDriver( 50 | new URL(PropertyHolder.testSuiteConfigurationProperties.getProperty("hubUrl").toString()), 51 | CapabilityFactory.getDesiredCapabilities()); 52 | else 53 | dr = new RemoteWebDriver( 54 | new URL(PropertyHolder.testSuiteConfigurationProperties.getProperty("hubUrl").toString()), 55 | CapabilityFactory.getDesiredCapabilities()); 56 | } else { 57 | logger.error("!!!!!!!!ERROR - Unable to create driver object"); 58 | System.exit(-1); 59 | } 60 | } catch (Exception e) { 61 | logger.error("!!!!!!!!!!ERROR - Unable to create browser object. "); 62 | e.printStackTrace(); 63 | } 64 | logger.info("********* After Webdriver object creation"); 65 | return dr; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/resources/ExtentConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | standard 6 | 7 | 8 | UTF-8 9 | 10 | 11 | https 12 | 13 | 14 | ToolsQA - Cucumber Framework 15 | 16 | 17 | ToolsQA - Cucumber Report 18 | 19 | 20 | yyyy-MM-dd 21 | 22 | 23 | HH:mm:ss 24 | 25 | 26 | 27 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /test-automation-framework/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | #Define root logger options 2 | log4j.rootLogger=INFO, file, console 3 | 4 | #Define console appender 5 | log4j.appender.console=org.apache.log4j.ConsoleAppender 6 | logrj.appender.console.Target=System.out 7 | log4j.appender.console.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.console.layout.ConversionPattern=%-5p %c{1} - %m%n 9 | 10 | #Define rolling file appender 11 | log4j.appender.file=org.apache.log4j.RollingFileAppender 12 | log4j.appender.file.File=logs/test_result.log 13 | log4j.appender.file.Append=true 14 | log4j.appender.file.ImmediateFlush=true 15 | log4j.appender.file.MaxFileSize=10MB 16 | log4j.appender.file.MaxBackupIndex=5 17 | log4j.appender.file.layout=org.apache.log4j.PatternLayout 18 | log4j.appender.file.layout.ConversionPattern=%d %d{Z} [%t] %-5p (%F:%L) - %m%n 19 | 20 | #Define loggers 21 | log4j.logger.com.journaldev.log4j=INFO, file, console 22 | log4j.logger.com.journaldev.log4j.logic=INFO, file, console 23 | 24 | #setting additivity 25 | log4j.additivity.com.journaldev.log4j=false 26 | log4j.additivity.com.journaldev.log4j.logic=false -------------------------------------------------------------------------------- /test-automation-framework/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | logs/customer_service.log 12 | 13 | logs/customer_service.%i.log.zip 14 | 1 15 | 3 16 | 17 | 18 | 19 | 10MB 20 | 21 | 22 | 23 | %date{YYYY-MM-dd HH:mm:ss} %level [%thread] %logger{10} [%file:%line] %msg%n 24 | 25 | 26 | 27 | 28 | --------------------------------------------------------------------------------