├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── custom.yml └── workflows │ └── ci.yml ├── .gitignore ├── README.md ├── img.png ├── img_1.png ├── img_2.png ├── img_3.png ├── img_4.png ├── img_5.png ├── img_6.png ├── infra ├── db │ └── sql │ │ └── init.sql └── docker-compose.yml ├── pom.xml └── src ├── main └── java │ └── com │ └── epam │ └── healenium │ ├── FrameworkPage.java │ ├── constants │ ├── BrowserType.java │ ├── DriverType.java │ ├── FrameworkType.java │ ├── LocatorType.java │ ├── PageUrl.java │ └── PagesType.java │ ├── selenide │ ├── pageobject │ │ ├── SelenideBasePage.java │ │ ├── callback │ │ │ └── SelenideCallbackPage.java │ │ ├── markup │ │ │ ├── SelenideMainPageWithFindBy.java │ │ │ └── SelenideMarkupPage.java │ │ └── testenv │ │ │ └── SelenideTestEnvPage.java │ └── search │ │ ├── Context.java │ │ ├── SelenideStrategy.java │ │ └── locators │ │ ├── SelenideClassNameStrategy.java │ │ ├── SelenideCssStrategy.java │ │ ├── SelenideIdStrategy.java │ │ ├── SelenideLinkTextStrategy.java │ │ ├── SelenideNameStrategy.java │ │ ├── SelenidePartialLinkStrategy.java │ │ ├── SelenideTagStrategy.java │ │ └── SelenideXPathStrategy.java │ ├── selenium │ ├── pageobject │ │ ├── SeleniumBasePage.java │ │ ├── callback │ │ │ └── CallbackPage.java │ │ ├── markup │ │ │ ├── MainPageWithFindBy.java │ │ │ └── MarkupPage.java │ │ └── testenv │ │ │ └── TestEnvPage.java │ └── search │ │ ├── Context.java │ │ ├── Strategy.java │ │ └── locators │ │ ├── ClassNameStrategy.java │ │ ├── CssStrategy.java │ │ ├── IdStrategy.java │ │ ├── LinkTextStrategy.java │ │ ├── NameStrategy.java │ │ ├── PartialLinkStrategy.java │ │ ├── TagStrategy.java │ │ └── XPathStrategy.java │ └── settings │ ├── DriverContext.java │ ├── FrameworkContext.java │ ├── IDriverInterface.java │ ├── IFrameworkInterface.java │ ├── drivers │ ├── LocalDriver.java │ ├── ProxyDriver.java │ └── RemoteDriver.java │ └── framework │ ├── JdiContext.java │ ├── SelenideContext.java │ └── SeleniumContext.java └── test ├── java └── com │ └── epam │ └── healenium │ └── tests │ ├── BaseTest.java │ ├── CssTest.java │ ├── GeneralTest.java │ ├── ParentChildTest.java │ ├── SemanticTest.java │ ├── SimpleTest.java │ ├── WaitTest.java │ └── XpathTest.java └── resources ├── healenium.properties ├── junit-platform.properties └── properties.json /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Create a report to help us improve 3 | title: "[BUG]: " 4 | labels: [ bug ] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Describe the bug 10 | description: | 11 | Provide a clear and concise description of what the bug is. 12 | placeholder: | 13 | Please add as many details as possible to avoid assumptions from our side. 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: reproduction 18 | attributes: 19 | label: How to reproduce the issue 20 | description: | 21 | Describe steps to reproduce the behavior. The more details you write, the faster we can help you. 22 | placeholder: | 23 | Please, describe step by step how you start Healenium: how you start Docker, how you create WebDriver, etc. 24 | render: shell 25 | validations: 26 | required: true 27 | - type: textarea 28 | id: logs 29 | attributes: 30 | label: Logs appeared during using Healenium 31 | description: | 32 | Provide logs you've seen during investigation 33 | placeholder: | 34 | Add as more logs as you can by your company policy. 35 | render: shell 36 | validations: 37 | required: true 38 | - type: textarea 39 | id: epx-behavior 40 | attributes: 41 | label: Expected behavior 42 | description: | 43 | Please provide clear and concise description of what you expected to happen. 44 | - type: textarea 45 | id: act-behavior 46 | attributes: 47 | label: Actual behavior 48 | description: | 49 | Please provide clear and concise description of what you've seen instead. 50 | - type: input 51 | id: web-hlm 52 | attributes: 53 | label: Healenium Proxy version 54 | description: What proxy version do you use? 55 | validations: 56 | required: true 57 | - type: input 58 | id: back-hlm 59 | attributes: 60 | label: Healenium Backend version 61 | description: What healenium-backend version do you use? 62 | validations: 63 | required: true 64 | - type: input 65 | id: selenium-version 66 | attributes: 67 | label: Selenium version 68 | description: What Selenium version do you use for testing? 69 | - type: textarea 70 | id: additional 71 | attributes: 72 | label: Additional context 73 | description: Add any other context about the problem here 74 | placeholder: For example, screenshot or using of additional frameworks like Sizzle library, Robot Framework or JDI, etc. If you can please, send a link to your project. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.yml: -------------------------------------------------------------------------------- 1 | name: Help-support template 2 | description: Describe you problem happened using Healenium and team will help 3 | title: "[Need support]: " 4 | labels: [ help wanted ] 5 | assignees: ElenaStepuro 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: | 10 | If you didn't see the video how to use Healenium, please, firstly, get it know on link https://healenium.io/ 11 | 12 | - type: textarea 13 | id: description 14 | attributes: 15 | label: Describe the problem 16 | description: | 17 | Provide a clear and concise description of the problem you've faced with. 18 | placeholder: | 19 | Please add as many details as possible to avoid assumptions from our side. 20 | validations: 21 | required: true 22 | 23 | - type: input 24 | id: web-hlm 25 | attributes: 26 | label: Healenium Proxy version 27 | description: What proxy version do you use? 28 | validations: 29 | required: true 30 | 31 | - type: input 32 | id: back-hlm 33 | attributes: 34 | label: Healenium Backend version 35 | description: What healenium-backend version do you use? 36 | validations: 37 | required: true 38 | 39 | - type: input 40 | id: selenium-version 41 | attributes: 42 | label: Selenium version 43 | description: What Selenium version do you use for testing? 44 | - type: textarea 45 | id: logs 46 | attributes: 47 | label: Logs appeared during using Healenium 48 | description: | 49 | Provide logs you've seen during investigation 50 | placeholder: | 51 | Add as more logs as you can by your company policy. 52 | render: shell 53 | validations: 54 | required: true 55 | 56 | - type: textarea 57 | id: additional 58 | attributes: 59 | label: Additional context 60 | description: Add any other context about the problem here 61 | placeholder: For example, screenshot or using of additional frameworks like Sizzle library, Robot Framework or JDI, etc. If you can please, send a link to your project. -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI Pipeline 2 | 3 | # Specify that the workflow is triggered manually 4 | on: 5 | workflow_dispatch: # This trigger allows manual execution through the UI 6 | 7 | jobs: 8 | build-and-test: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | # 1. Clone the repository 13 | - name: Checkout repository 14 | uses: actions/checkout@v3 15 | 16 | # 2. Set up Java and Maven 17 | - name: Setup JDK 18 | uses: actions/setup-java@v3 19 | with: 20 | distribution: 'temurin' # Use the Temurin JDK distribution 21 | java-version: '17' # Specify the Java version (replace with yours if different) 22 | cache: 'maven' # Enable dependency caching for Maven 23 | 24 | 25 | # 3. Install Docker Compose manually (for older versions) 26 | - name: Install Docker Compose Manually 27 | run: | 28 | curl -L "https://github.com/docker/compose/releases/download/v2.35.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 29 | sudo chmod +x /usr/local/bin/docker-compose 30 | 31 | - name: Verify Docker Compose installation 32 | run: docker compose --version 33 | 34 | # 4. Start all services using Docker Compose 35 | - name: Start services via Docker Compose 36 | run: docker compose -f ./infra/docker-compose.yml up -d 37 | 38 | # 5. Wait for services to be healthy (healthcheck for dependent services) 39 | - name: Wait for services to be ready 40 | run: | 41 | sleep 10 # Wait until all services are accessible 42 | docker ps 43 | 44 | # 6. Restore a PostgreSQL database dump 45 | - name: Restore PostgreSQL database dump 46 | run: | 47 | docker exec -i postgres-db psql -U healenium_user -d healenium < ./infra/dump.sql 48 | 49 | # 7. Build the project and load dependencies 50 | - name: Build with Maven 51 | run: mvn compile 52 | 53 | # 8. Run tests 54 | - name: Run Maven tests 55 | run: mvn test -Dtest=SimpleTest 56 | 57 | # 9. Save the database dump 58 | - name: Dump PostgreSQL database 59 | run: | 60 | docker exec -i postgres-db pg_dump -U healenium_user -d healenium > ./infra/dump.sql 61 | 62 | # 10. Commit the updated database dump to the repository 63 | - name: Commit and push database dump 64 | run: | 65 | git config --global user.name "github-actions[bot]" 66 | git config --global user.email "github-actions[bot]@users.noreply.github.com" 67 | git add ./infra/dump.sql 68 | git commit -m "Auto-update database dump" || echo "No changes to commit." # Skip commit if the file hasn't changed 69 | git push origin HEAD:master --force # Force push changes to the repository 70 | env: 71 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use token for authentication 72 | 73 | 74 | # 11. Finalize by cleaning up containers 75 | - name: Shutdown services 76 | if: always() 77 | run: docker compose -f ./infra/docker-compose.yml down 78 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | /out 4 | 5 | # Ignore Gradle GUI config 6 | gradle-app.setting 7 | 8 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 9 | !gradle-wrapper.jar 10 | 11 | # Cache of project 12 | .gradletasknamecache 13 | chromedriver* 14 | 15 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 16 | # gradle/wrapper/gradle-wrapper.properties 17 | /healenium-web-selenium/.allure/ 18 | /healenium-web-selenium/allure-results/ 19 | /healenium-web-htmlelements/target/ 20 | /healenium-web-selenide/target/ 21 | /healenium-web-selenium/target/ 22 | /target/ 23 | /healenium-web-selenide/.allure/ 24 | /healenium-web-selenide/build/ 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # healenium-example-maven 2 | Java + Maven + Junit5 project with healenium usage example 3 | 4 | ### To setup Healenium see the tutorial: https://www.youtube.com/watch?v=Ed5HyfwZhq4 5 | 6 | ## How to start 7 | ### 1.Start Healenium backend from infra folder 8 | 9 | ```cd infra``` 10 | 11 | ```docker-compose up -d``` 12 | 13 | To download this file into your project use this command: 14 | 15 | ```$ curl https://raw.githubusercontent.com/healenium/healenium-example-maven/master/infra/docker-compose.yml -o docker-compose.yml``` 16 | 17 | Create /db/sql folder on the same level in your project. Add init.sql file into ./db/sql/init.sql folder in your project via command: 18 | 19 | ```$ curl https://raw.githubusercontent.com/healenium/healenium-client/master/example/init.sql -o init.sql``` 20 | 21 | Verify that images ```healenium/hlm-backend:3.4.1``` and ```postgres:11-alpine``` and ```healenium/hlm-selector-imitator:1.2``` are up and running 22 | 23 | ### 2. Project structure 24 | ``` 25 | |__infra 26 | |__db/sql 27 | |__init.sql 28 | |__docker-compose.yml 29 | |__src/main/java/ 30 | |__src/test/java/ 31 | |__pom.xml 32 | ``` 33 | 34 | ### 3.Run test in terminal with maven 35 | 36 | In ```BaseTest.java``` class select necessary driver: **LOCAL**, **PROXY** or **REMOTE** and browser to run: chrome, firefox or edge. 37 | 38 | ```driver = new DriverContext(DriverType.LOCAL).getDriver(BrowserType.CHROME);``` 39 | 40 | **LOCAL** - used for local run. It's been set by default in BaseTest.java class. For this driver should be used docker-compose file from test example. 41 | 42 | **PROXY** - used if you're running tests using healenium-proxy. For this driver you need to set docker-compose containers as in example by link: 43 | https://github.com/healenium/healenium-example-dotnet/blob/master/infra/docker-compose.yml 44 | 45 | **REMOTE** - used if you-re running test on remote machine. Do not forget to provide necessary host. In this test example it's been used remote machine with Selenoid. 46 | 47 | In ```BaseTest.java``` class select necessary framework: **SELENIUM** or **SELENIDE**. 48 | 49 | ```pages = new FrameworkContext(FrameworkType.SELENIDE, driver).setFramework();``` 50 | 51 | If you want to execute all tests, please use the command: ```mvn clean test``` 52 | 53 | 54 | ### 4.After test execution you should see generated report link in command line logs 55 | 56 | ![img.png](img.png) 57 | 58 | Report contains only healed locators with old-new values and a button that tells if healing was successful for further algorithm corrections 59 | 60 | ![img_1.png](img_1.png) 61 | 62 | ### 5. Screenshots 63 | 64 | Also you could take a screenshots for your com.epam.healenium.tests like it implements here: BaseTest.screenshot 65 | ``` 66 | public byte[] screenshot() { 67 | return ((TakesScreenshot) driver.getDelegate()).getScreenshotAs(OutputType.BYTES); 68 | } 69 | ``` 70 | ### 6. @DisableHealing annotation 71 | 72 | If don't want to use Healenium in some methods just use @DisableHealing annotation. 73 | > The example of usage you can find here: MainPageWithFindBy.checkLocatorTestButtonDontHealing 74 | 75 | ![img_2.png](img_2.png) 76 | 77 | ### 7. Plugin Healenium for Intellij IDE 78 | 79 | For updating broken locators you could use Plugin "Healenium" for Intellij IDE (https://plugins.jetbrains.com/plugin/14178-healenium). 80 | 81 | With this plugin you can update your locators: 82 | * on class level 83 | 84 | ![update_on_class_level](img_6.png) 85 | * or on variable level 86 | 87 | ![update_on_class_level](img_5.png) 88 | 89 | ![element_update](img_4.png) 90 | -------------------------------------------------------------------------------- /img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/healenium/healenium-example-maven/1777fef006058bfc85513e306d65ae037aa02c13/img.png -------------------------------------------------------------------------------- /img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/healenium/healenium-example-maven/1777fef006058bfc85513e306d65ae037aa02c13/img_1.png -------------------------------------------------------------------------------- /img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/healenium/healenium-example-maven/1777fef006058bfc85513e306d65ae037aa02c13/img_2.png -------------------------------------------------------------------------------- /img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/healenium/healenium-example-maven/1777fef006058bfc85513e306d65ae037aa02c13/img_3.png -------------------------------------------------------------------------------- /img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/healenium/healenium-example-maven/1777fef006058bfc85513e306d65ae037aa02c13/img_4.png -------------------------------------------------------------------------------- /img_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/healenium/healenium-example-maven/1777fef006058bfc85513e306d65ae037aa02c13/img_5.png -------------------------------------------------------------------------------- /img_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/healenium/healenium-example-maven/1777fef006058bfc85513e306d65ae037aa02c13/img_6.png -------------------------------------------------------------------------------- /infra/db/sql/init.sql: -------------------------------------------------------------------------------- 1 | CREATE SCHEMA healenium AUTHORIZATION healenium_user; 2 | GRANT USAGE ON SCHEMA healenium TO healenium_user; -------------------------------------------------------------------------------- /infra/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | services: 3 | 4 | postgres-db: 5 | image: postgres:15.5-alpine 6 | container_name: postgres-db 7 | ports: 8 | - "5432:5432" 9 | volumes: 10 | - ./db/sql/init.sql:/docker-entrypoint-initdb.d/init.sql 11 | restart: always 12 | environment: 13 | - POSTGRES_DB=healenium 14 | - POSTGRES_USER=healenium_user 15 | - POSTGRES_PASSWORD=YDk2nmNs4s9aCP6K 16 | networks: 17 | - healenium 18 | 19 | healenium: 20 | image: healenium/hlm-backend:3.4.6 21 | ports: 22 | - "7878:7878" 23 | links: 24 | - postgres-db 25 | environment: 26 | - SPRING_POSTGRES_DB=healenium 27 | - SPRING_POSTGRES_SCHEMA=healenium 28 | - SPRING_POSTGRES_USER=healenium_user 29 | - SPRING_POSTGRES_PASSWORD=YDk2nmNs4s9aCP6K 30 | - SPRING_POSTGRES_DB_HOST=postgres-db 31 | - KEY_SELECTOR_URL=false 32 | - COLLECT_METRICS=true 33 | - FIND_ELEMENTS_AUTO_HEALING=false 34 | - HLM_LOG_LEVEL=info 35 | networks: 36 | - healenium 37 | 38 | selector-imitator: 39 | image: healenium/hlm-selector-imitator:1.4 40 | container_name: selector-imitator 41 | restart: on-failure 42 | ports: 43 | - "8000:8000" 44 | networks: 45 | - healenium 46 | 47 | networks: 48 | healenium: 49 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | healenium-example-maven 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 17 13 | 17 14 | 15 | 5.9.1 16 | 2.13.0 17 | 2.2 18 | 5.9.2 19 | 20 | 4.25.0 21 | 7.0.0 22 | 1.3.22 23 | 24 | 3.5.4 25 | 26 | 27 | 28 | 29 | com.epam.healenium 30 | healenium-web 31 | ${healenium.version} 32 | 33 | 34 | 35 | org.seleniumhq.selenium 36 | selenium-java 37 | ${selenium.version} 38 | 39 | 40 | 41 | org.seleniumhq.selenium 42 | selenium-api 43 | ${selenium.version} 44 | 45 | 46 | 47 | 48 | io.cucumber 49 | cucumber-java 50 | 7.1.0 51 | 52 | 53 | info.cukes 54 | cucumber-junit 55 | 1.2.4 56 | 57 | 58 | com.codeborne 59 | selenide 60 | ${selenide.version} 61 | 62 | 63 | net.bytebuddy 64 | byte-buddy 65 | 1.3.16 66 | runtime 67 | 68 | 69 | 70 | com.epam.jdi 71 | jdi-light 72 | ${jdi.version} 73 | 74 | 75 | 76 | org.junit.jupiter 77 | junit-jupiter 78 | ${junit.version} 79 | 80 | 81 | 82 | org.junit.jupiter 83 | junit-jupiter-api 84 | ${junit.version} 85 | compile 86 | 87 | 88 | 89 | org.junit.jupiter 90 | junit-jupiter-params 91 | ${junit.version} 92 | test 93 | 94 | 95 | 96 | org.junit.jupiter 97 | junit-jupiter-engine 98 | ${junit.version} 99 | test 100 | 101 | 102 | 103 | org.apache.logging.log4j 104 | log4j-api 105 | ${log4j.version} 106 | 107 | 108 | org.apache.logging.log4j 109 | log4j-core 110 | ${log4j.version} 111 | 112 | 113 | 114 | org.hamcrest 115 | hamcrest-core 116 | ${hamcrest.version} 117 | 118 | 119 | io.github.bonigarcia 120 | webdrivermanager 121 | ${webdrivermanager.version} 122 | 123 | 124 | com.epam.reportportal 125 | logger-java-logback 126 | 5.1.6 127 | 128 | 129 | ch.qos.logback 130 | logback-classic 131 | 1.2.10 132 | 133 | 134 | com.epam.reportportal 135 | agent-java-junit5 136 | 5.1.10 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | org.apache.maven.plugins 150 | maven-surefire-plugin 151 | 2.22.1 152 | 153 | 154 | org.apache.maven.plugins 155 | maven-compiler-plugin 156 | 3.8.1 157 | 158 | 10 159 | 10 160 | 161 | 162 | 163 | maven-surefire-plugin 164 | 3.0.0-M5 165 | 166 | 167 | 168 | junit.jupiter.extensions.autodetection.enabled = true 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/FrameworkPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium; 2 | 3 | import com.epam.healenium.constants.LocatorType; 4 | 5 | public abstract class FrameworkPage { 6 | 7 | public FrameworkPage openPage() { 8 | return null; 9 | } 10 | 11 | public FrameworkPage findTestElement(LocatorType css, String s) { 12 | return null; 13 | } 14 | 15 | public FrameworkPage clickSubmitButton() { 16 | return null; 17 | } 18 | 19 | public FrameworkPage clickAddSquareButton() { 20 | return null; 21 | } 22 | 23 | public FrameworkPage clickUpdateSquareButton() { 24 | return null; 25 | } 26 | 27 | public boolean verifySquareElement() { 28 | return false; 29 | } 30 | 31 | public FrameworkPage clickTestButton() { 32 | return null; 33 | } 34 | 35 | public FrameworkPage confirmAlert() { 36 | return null; 37 | } 38 | 39 | public FrameworkPage clickElementByChangeID() { 40 | return null; 41 | } 42 | 43 | public FrameworkPage clickElementByChangeClassName() { 44 | return null; 45 | } 46 | 47 | public FrameworkPage clickElementByChangeTagName() { 48 | return null; 49 | } 50 | 51 | public FrameworkPage clickElementByChangeName() { 52 | return null; 53 | } 54 | 55 | public FrameworkPage findElementByChangeLinkText() { 56 | return null; 57 | } 58 | 59 | public FrameworkPage findCheckBox1() { 60 | return null; 61 | } 62 | 63 | public FrameworkPage findCheckBox2() { 64 | return null; 65 | } 66 | 67 | public FrameworkPage findCheckBox3() { 68 | return null; 69 | } 70 | 71 | public FrameworkPage clickSubmitButtonForCheckBox() { 72 | return null; 73 | } 74 | 75 | public FrameworkPage findElementEnableToDisable() { 76 | return null; 77 | } 78 | 79 | public FrameworkPage findCheckBoxEnableToDisable() { 80 | return null; 81 | } 82 | 83 | public FrameworkPage generateMarkup() { 84 | return null; 85 | } 86 | 87 | public boolean displayedText() { 88 | return false; 89 | } 90 | 91 | public int selectAllCheckboxes() { 92 | return 0; 93 | } 94 | 95 | public int verifyAllCheckboxesChecked() { 96 | return 0; 97 | } 98 | 99 | public int verifyAllCheckboxesUnchecked() { 100 | return 0; 101 | } 102 | 103 | public boolean checkLocatorTestButtonDontHealing() { 104 | return false; 105 | } 106 | 107 | public FrameworkPage selectFirstCheckbox() { 108 | return null; 109 | } 110 | 111 | public boolean verifyFirstAccountCheckbox() { 112 | return false; 113 | } 114 | 115 | public FrameworkPage selectFirstAccountCheckbox() { 116 | return null; 117 | } 118 | 119 | public boolean groupInputEnabled() { 120 | return false; 121 | } 122 | 123 | public void verifyInputText() { 124 | } 125 | 126 | public void fillInputsGroup() { 127 | } 128 | 129 | public boolean testButtonEnable() { 130 | return false; 131 | } 132 | 133 | public FrameworkPage clickTestGeneratedButton() { 134 | return null; 135 | } 136 | 137 | public FrameworkPage clickTestButtonWaitor(int i) { 138 | return null; 139 | } 140 | 141 | public FrameworkPage findElementsUnderParent(String parentXpath, String childXpath) { 142 | return null; 143 | } 144 | 145 | public FrameworkPage clickFormButton() { 146 | return null; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/constants/BrowserType.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.constants; 2 | 3 | public enum BrowserType { 4 | CHROME, 5 | FIREFOX, 6 | SAFARI, 7 | IE; 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/constants/DriverType.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.constants; 2 | 3 | public enum DriverType { 4 | LOCAL, 5 | REMOTE, 6 | PROXY; 7 | 8 | DriverType() { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/constants/FrameworkType.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.constants; 2 | 3 | public enum FrameworkType { 4 | SELENIUM("selenium"), 5 | SELENIDE("selenide"), 6 | JDI("jdi"); 7 | 8 | private final String typeName; 9 | 10 | FrameworkType(String name) { 11 | this.typeName = name; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/constants/LocatorType.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.constants; 2 | 3 | public enum LocatorType { 4 | XPATH("xpath"), 5 | CSS("css"), 6 | ID("id"), 7 | CLASS_NAME("className"), 8 | LINK_TEXT("linkText"), 9 | NAME("name"), 10 | PARTIAL_LINK_TEXT("partialLinkText"), 11 | TAG_NAME("tagName"); 12 | 13 | private final String typeName; 14 | 15 | LocatorType(String name) { 16 | this.typeName = name; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/constants/PageUrl.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.constants; 2 | 3 | public enum PageUrl { 4 | TEST_ENV_URL("https://elenastepuro.github.io/test_env/index.html"), 5 | CALLBACK_URL("https://mdn.github.io/web-components-examples/life-cycle-callbacks/"), 6 | MARKUP_URL("http://sha-test-app.herokuapp.com/"); 7 | 8 | private final String urlName; 9 | 10 | PageUrl(String name) { 11 | this.urlName = name; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return urlName; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/constants/PagesType.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.constants; 2 | 3 | public enum PagesType { 4 | TEST_ENV("Test env page"), 5 | MARKUP("Markup page"), 6 | MARKUP_FIND_BY("Markup with find by"), 7 | CALLBACK("Callback page"); 8 | 9 | private String pagetype; 10 | PagesType(String page) { 11 | pagetype=page; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/pageobject/SelenideBasePage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.pageobject; 2 | 3 | import com.codeborne.selenide.Selenide; 4 | import com.epam.healenium.FrameworkPage; 5 | 6 | import static com.codeborne.selenide.Selenide.page; 7 | 8 | public class SelenideBasePage extends FrameworkPage { 9 | 10 | public SelenideBasePage confirmAlert(){ 11 | Selenide.switchTo().alert().accept(); 12 | return page(SelenideBasePage.class); 13 | } 14 | 15 | public String getAlertText(){ 16 | return Selenide.switchTo().alert().getText(); 17 | } 18 | 19 | public void refreshPage(){ 20 | Selenide.refresh(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/pageobject/callback/SelenideCallbackPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.pageobject.callback; 2 | 3 | import com.epam.healenium.constants.PageUrl; 4 | import com.epam.healenium.selenide.pageobject.SelenideBasePage; 5 | import org.openqa.selenium.By; 6 | 7 | import static com.codeborne.selenide.Selenide.$; 8 | import static com.codeborne.selenide.Selenide.open; 9 | 10 | public class SelenideCallbackPage extends SelenideBasePage { 11 | 12 | private By addSquareButton = By.xpath("//button[contains(@class, 'add')]"); 13 | private By updateSquareButton = By.xpath("//button[contains(@class, 'update')]"); 14 | 15 | private By testButtonCss = By.cssSelector("[c='red']"); 16 | 17 | public SelenideCallbackPage openPage() { 18 | open(String.valueOf(PageUrl.CALLBACK_URL)); 19 | return this; 20 | } 21 | 22 | public SelenideCallbackPage clickAddSquareButton() { 23 | $(addSquareButton).click(); 24 | return this; 25 | } 26 | 27 | public boolean verifySquareElement() { 28 | return $(testButtonCss).isEnabled(); 29 | } 30 | 31 | public SelenideCallbackPage clickUpdateSquareButton() { 32 | $(updateSquareButton).click(); 33 | return this; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/pageobject/markup/SelenideMainPageWithFindBy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.pageobject.markup; 2 | 3 | import com.codeborne.selenide.Condition; 4 | import com.codeborne.selenide.Selenide; 5 | import com.codeborne.selenide.SelenideElement; 6 | import com.codeborne.selenide.ex.ElementNotFound; 7 | import com.epam.healenium.annotation.DisableHealing; 8 | import com.epam.healenium.constants.PageUrl; 9 | import com.epam.healenium.selenide.pageobject.SelenideBasePage; 10 | import org.openqa.selenium.support.FindBy; 11 | import org.openqa.selenium.support.How; 12 | 13 | import static com.codeborne.selenide.Selenide.open; 14 | import static com.codeborne.selenide.Selenide.page; 15 | 16 | public class SelenideMainPageWithFindBy extends SelenideBasePage { 17 | @FindBy(how = How.XPATH, using = "//button[contains(@class,'default-btn')]") 18 | public SelenideElement testButton; 19 | 20 | @FindBy(how = How.ID, using = "markup-generation-button") 21 | public SelenideElement generateMarkupBtnId; 22 | 23 | public SelenideMainPageWithFindBy openPage(){ 24 | open(PageUrl.MARKUP_URL.toString()); 25 | return page(SelenideMainPageWithFindBy.class); 26 | } 27 | 28 | public SelenideMainPageWithFindBy generateMarkup() { 29 | generateMarkupBtnId.shouldBe(Condition.visible).click(); 30 | return page(SelenideMainPageWithFindBy.class); 31 | } 32 | 33 | public SelenideMainPageWithFindBy clickTestButton() { 34 | testButton.shouldBe(Condition.visible).click(); 35 | return page(SelenideMainPageWithFindBy.class); 36 | } 37 | 38 | @DisableHealing 39 | public boolean checkLocatorTestButtonDontHealing() { 40 | try { 41 | testButton.shouldBe(Condition.visible).click(); 42 | return false; 43 | } catch (ElementNotFound e) { 44 | return true; 45 | } 46 | } 47 | 48 | public SelenideMainPageWithFindBy confirmAlert(){ 49 | Selenide.switchTo().alert().accept(); 50 | return page(SelenideMainPageWithFindBy.class); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/pageobject/markup/SelenideMarkupPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.pageobject.markup; 2 | 3 | import com.codeborne.selenide.Condition; 4 | import com.codeborne.selenide.ex.ElementNotFound; 5 | import com.epam.healenium.annotation.DisableHealing; 6 | import com.epam.healenium.constants.PageUrl; 7 | import com.epam.healenium.selenide.pageobject.SelenideBasePage; 8 | import org.openqa.selenium.By; 9 | 10 | import java.time.Duration; 11 | 12 | import static com.codeborne.selenide.Condition.visible; 13 | import static com.codeborne.selenide.Selenide.*; 14 | 15 | public class SelenideMarkupPage extends SelenideBasePage { 16 | 17 | private By generateMarkupBtnId = By.id("markup-generation-button"); 18 | private By testButton = By.className("default-btn"); 19 | private By testGeneratedButton = By.id("random-id"); 20 | 21 | private By checkboxAccount = By.xpath("//*[@class='checkbox checkbox_size_m checkbox_theme_alfa-on-white']"); 22 | private By textFirstSelect = By.xpath("(//*[text()='Select Account'])[1]"); 23 | 24 | private By firstCheckboxChecked = By.xpath("//*[text()='Current account']//parent::label[contains(@class,'checked')]"); 25 | private By checkboxChecked = By.xpath("//label[contains(@class,'checkbox_checked')]"); 26 | private By checkboxUnchecked = By.xpath("//label[not(contains(@class,'checkbox_checked'))]"); 27 | 28 | private By parentInput = By.xpath("//*[contains(@class,'input-group') and @role='group']");//span[@class='input__box']"); 29 | private By childInput = By.xpath(".//*[@value='']"); 30 | 31 | 32 | public SelenideMarkupPage openPage() { 33 | open(PageUrl.MARKUP_URL.toString()); 34 | return page(SelenideMarkupPage.class); 35 | } 36 | 37 | public SelenideMarkupPage generateMarkup() { 38 | $(generateMarkupBtnId).click(); 39 | return page(SelenideMarkupPage.class); 40 | } 41 | 42 | public SelenideMarkupPage clickTestButton() { 43 | $(testButton).click(); 44 | return page(SelenideMarkupPage.class); 45 | } 46 | 47 | public SelenideMarkupPage clickTestGeneratedButton() { 48 | $(testGeneratedButton).click(); 49 | return page(SelenideMarkupPage.class); 50 | } 51 | 52 | @DisableHealing 53 | public boolean displayedText() { 54 | try { 55 | return $(textFirstSelect).shouldBe(Condition.visible).isEnabled(); 56 | } catch (ElementNotFound e1) { 57 | return false; 58 | } 59 | } 60 | 61 | public SelenideMarkupPage selectFirstCheckbox() { 62 | $$(checkboxAccount).get(0).click(); 63 | return page(SelenideMarkupPage.class); 64 | } 65 | 66 | public boolean verifyFirstCheckbox() { 67 | return $$(checkboxAccount).get(0).isEnabled(); 68 | } 69 | 70 | public boolean verifyFirstAccountCheckbox() { 71 | return $(firstCheckboxChecked).isEnabled(); 72 | } 73 | 74 | public SelenideMarkupPage selectFirstAccountCheckbox() { 75 | $(firstCheckboxChecked).click(); 76 | return page(SelenideMarkupPage.class); 77 | } 78 | 79 | @DisableHealing 80 | public boolean testButtonEnable() { 81 | try { 82 | return $(testGeneratedButton).isEnabled(); 83 | } catch (ElementNotFound e) { 84 | return false; 85 | } 86 | } 87 | 88 | @DisableHealing 89 | public boolean groupInputEnabled() { 90 | try { 91 | return $(parentInput).isEnabled() 92 | && $(By.xpath("//*[@placeholder='Just some text']")) 93 | .isEnabled(); 94 | } catch (ElementNotFound e1) { 95 | return false; 96 | } 97 | } 98 | 99 | public SelenideMarkupPage clickTestButtonWaitor(int seconds) { 100 | $(testButton).shouldBe(visible, Duration.ofSeconds(seconds)).click(); 101 | return page(SelenideMarkupPage.class); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/pageobject/testenv/SelenideTestEnvPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.pageobject.testenv; 2 | 3 | import com.epam.healenium.constants.LocatorType; 4 | import com.epam.healenium.constants.PageUrl; 5 | import com.epam.healenium.selenide.pageobject.SelenideBasePage; 6 | import com.epam.healenium.selenide.search.Context; 7 | import org.openqa.selenium.By; 8 | import org.openqa.selenium.WebElement; 9 | 10 | import java.util.List; 11 | 12 | import static com.codeborne.selenide.Selenide.$; 13 | import static com.codeborne.selenide.Selenide.open; 14 | import static org.junit.jupiter.api.Assertions.assertTrue; 15 | 16 | public class SelenideTestEnvPage extends SelenideBasePage { 17 | 18 | private By submitButton = By.id("Submit"); 19 | private By formButton = By.id("Submit_checkbox"); 20 | 21 | public SelenideTestEnvPage openPage() { 22 | open(PageUrl.TEST_ENV_URL.toString()); 23 | return this; 24 | } 25 | 26 | public SelenideTestEnvPage findTestElement(LocatorType type, String selector) { 27 | boolean result = new Context(type).executeStrategy(selector); 28 | assertTrue(result); 29 | return this; 30 | } 31 | 32 | public SelenideTestEnvPage clickSubmitButton() { 33 | $(submitButton).click(); 34 | return this; 35 | } 36 | 37 | public SelenideTestEnvPage findElementsUnderParent(String parentXpath, String childXpath) { 38 | List formElements = $(By.xpath(parentXpath)).findElements(By.xpath("." + childXpath)); 39 | formElements.forEach(f -> f.click()); 40 | return this; 41 | } 42 | 43 | public SelenideTestEnvPage clickFormButton(){ 44 | $(formButton).click(); 45 | return this; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/Context.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search; 2 | 3 | import com.epam.healenium.constants.LocatorType; 4 | import com.epam.healenium.selenide.search.locators.*; 5 | 6 | public class Context { 7 | private SelenideStrategy strategy; 8 | 9 | public Context(LocatorType type) { 10 | switch (type) { 11 | case XPATH: 12 | this.strategy = new SelenideXPathStrategy(); 13 | break; 14 | case CSS: 15 | this.strategy = new SelenideCssStrategy(); 16 | break; 17 | case ID: 18 | this.strategy = new SelenideIdStrategy(); 19 | break; 20 | case CLASS_NAME: 21 | this.strategy = new SelenideClassNameStrategy(); 22 | break; 23 | case LINK_TEXT: 24 | this.strategy = new SelenideLinkTextStrategy(); 25 | break; 26 | case PARTIAL_LINK_TEXT: 27 | this.strategy = new SelenidePartialLinkStrategy(); 28 | break; 29 | case TAG_NAME: 30 | this.strategy = new SelenideTagStrategy(); 31 | break; 32 | case NAME: 33 | this.strategy = new SelenideNameStrategy(); 34 | break; 35 | } 36 | } 37 | 38 | public boolean executeStrategy(String selector) { 39 | return strategy.doAction(selector); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/SelenideStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search; 2 | 3 | public interface SelenideStrategy { 4 | boolean doAction(String selector); 5 | } -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/locators/SelenideClassNameStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search.locators; 2 | 3 | import com.epam.healenium.selenide.search.SelenideStrategy; 4 | import org.openqa.selenium.By; 5 | 6 | import static com.codeborne.selenide.Selenide.$; 7 | 8 | public class SelenideClassNameStrategy implements SelenideStrategy { 9 | 10 | public SelenideClassNameStrategy() { 11 | } 12 | 13 | @Override 14 | public boolean doAction(String selector) { 15 | return $(By.className(selector)).isDisplayed(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/locators/SelenideCssStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search.locators; 2 | 3 | import com.epam.healenium.selenide.search.SelenideStrategy; 4 | import org.openqa.selenium.By; 5 | 6 | import static com.codeborne.selenide.Selenide.$; 7 | 8 | public class SelenideCssStrategy implements SelenideStrategy { 9 | public SelenideCssStrategy() { 10 | } 11 | 12 | @Override 13 | public boolean doAction(String selector) { 14 | return $(By.cssSelector(selector)).isDisplayed(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/locators/SelenideIdStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search.locators; 2 | 3 | import com.epam.healenium.selenide.search.SelenideStrategy; 4 | import org.openqa.selenium.By; 5 | 6 | import static com.codeborne.selenide.Selenide.$; 7 | 8 | public class SelenideIdStrategy implements SelenideStrategy { 9 | public SelenideIdStrategy() { 10 | } 11 | 12 | @Override 13 | public boolean doAction(String selector) { 14 | return $(By.id(selector)).isDisplayed(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/locators/SelenideLinkTextStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search.locators; 2 | 3 | import com.epam.healenium.selenide.search.SelenideStrategy; 4 | import org.openqa.selenium.By; 5 | 6 | import static com.codeborne.selenide.Selenide.$; 7 | 8 | public class SelenideLinkTextStrategy implements SelenideStrategy { 9 | public SelenideLinkTextStrategy() { 10 | } 11 | 12 | @Override 13 | public boolean doAction(String selector) { 14 | return $(By.linkText(selector)).isDisplayed(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/locators/SelenideNameStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search.locators; 2 | 3 | import com.epam.healenium.selenide.search.SelenideStrategy; 4 | import org.openqa.selenium.By; 5 | 6 | import static com.codeborne.selenide.Selenide.$; 7 | 8 | public class SelenideNameStrategy implements SelenideStrategy { 9 | public SelenideNameStrategy() { 10 | } 11 | 12 | @Override 13 | public boolean doAction(String selector) { 14 | return $(By.name(selector)).isDisplayed(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/locators/SelenidePartialLinkStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search.locators; 2 | 3 | import com.epam.healenium.selenide.search.SelenideStrategy; 4 | import org.openqa.selenium.By; 5 | 6 | import static com.codeborne.selenide.Selenide.$; 7 | 8 | public class SelenidePartialLinkStrategy implements SelenideStrategy { 9 | 10 | public SelenidePartialLinkStrategy() { 11 | } 12 | 13 | @Override 14 | public boolean doAction(String selector) { 15 | return $(By.partialLinkText(selector)).isDisplayed(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/locators/SelenideTagStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search.locators; 2 | 3 | import com.epam.healenium.selenide.search.SelenideStrategy; 4 | import org.openqa.selenium.By; 5 | 6 | import static com.codeborne.selenide.Selenide.$; 7 | 8 | public class SelenideTagStrategy implements SelenideStrategy { 9 | 10 | public SelenideTagStrategy() { 11 | } 12 | 13 | @Override 14 | public boolean doAction(String selector) { 15 | return $(By.tagName(selector)).isDisplayed(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenide/search/locators/SelenideXPathStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenide.search.locators; 2 | 3 | import com.epam.healenium.SelfHealingDriver; 4 | import com.epam.healenium.selenide.search.SelenideStrategy; 5 | import org.openqa.selenium.By; 6 | 7 | import static com.codeborne.selenide.Selenide.$; 8 | 9 | public class SelenideXPathStrategy implements SelenideStrategy { 10 | 11 | public SelenideXPathStrategy() { 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return $(By.xpath(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/pageobject/SeleniumBasePage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.pageobject; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import org.openqa.selenium.Alert; 5 | import org.openqa.selenium.TimeoutException; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.support.ui.ExpectedConditions; 8 | import org.openqa.selenium.support.ui.WebDriverWait; 9 | 10 | import java.time.Duration; 11 | 12 | public class SeleniumBasePage extends FrameworkPage { 13 | protected String mainPageUrl = "https://elenastepuro.github.io/test_env/index.html"; 14 | protected WebDriver driver; 15 | 16 | public SeleniumBasePage(WebDriver driver) { 17 | this.driver = driver; 18 | } 19 | 20 | public static void sleepForSecondsToSeeTheAlertWhileTestIsRunning(int seconds) { 21 | try { 22 | Thread.sleep(seconds * 1000); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | 28 | public String getAlertText() { 29 | sleepForSecondsToSeeTheAlertWhileTestIsRunning(1); 30 | String foundAlertText = ""; 31 | WebDriverWait wait = new WebDriverWait(driver, Duration.ZERO /*timeout in seconds*/); 32 | try { 33 | wait.until(ExpectedConditions.alertIsPresent()); 34 | foundAlertText = driver.switchTo().alert().getText(); 35 | } catch (TimeoutException eTO) { 36 | foundAlertText = "no alert text"; 37 | } 38 | return foundAlertText; 39 | } 40 | 41 | public SeleniumBasePage confirmAlert() { 42 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30) /*timeout in seconds*/); 43 | wait.until(ExpectedConditions.alertIsPresent()); 44 | Alert alert = driver.switchTo().alert(); 45 | alert.accept(); 46 | return this; 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/pageobject/callback/CallbackPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.pageobject.callback; 2 | 3 | import com.epam.healenium.constants.PageUrl; 4 | import com.epam.healenium.selenium.pageobject.SeleniumBasePage; 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.WebDriver; 7 | 8 | public class CallbackPage extends SeleniumBasePage { 9 | 10 | private By addSquareButton = By.xpath("//button[contains(@class, 'add')]"); 11 | private By updateSquareButton = By.xpath("//button[contains(@class, 'update')]"); 12 | private By removeSquareButton = By.xpath("//button[contains(@class, 'remove')]"); 13 | 14 | private By testButtonCss = By.cssSelector("[color='red']"); 15 | 16 | public CallbackPage(WebDriver driver) { 17 | super(driver); 18 | } 19 | 20 | public CallbackPage clickAddSquareButton() { 21 | driver.findElement(addSquareButton).click(); 22 | return this; 23 | } 24 | 25 | public boolean verifySquareElement() { 26 | return driver.findElement(testButtonCss).isEnabled(); 27 | } 28 | 29 | public CallbackPage clickUpdateSquareButton() { 30 | driver.findElement(updateSquareButton).click(); 31 | return this; 32 | } 33 | 34 | public CallbackPage clickRemoveSquareButton() { 35 | driver.findElement(removeSquareButton).click(); 36 | return this; 37 | } 38 | 39 | public CallbackPage openPage() { 40 | driver.get(String.valueOf(PageUrl.CALLBACK_URL)); 41 | return this; 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/pageobject/markup/MainPageWithFindBy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.pageobject.markup; 2 | 3 | import com.epam.healenium.annotation.DisableHealing; 4 | import com.epam.healenium.selenium.pageobject.SeleniumBasePage; 5 | import com.epam.healenium.selenium.pageobject.testenv.TestEnvPage; 6 | import io.qameta.allure.Step; 7 | import org.glassfish.jaxb.runtime.v2.runtime.unmarshaller.TagName; 8 | import org.openqa.selenium.By; 9 | import org.openqa.selenium.NoSuchElementException; 10 | import org.openqa.selenium.WebDriver; 11 | import org.openqa.selenium.WebElement; 12 | import org.openqa.selenium.interactions.Actions; 13 | import org.openqa.selenium.support.FindBy; 14 | import org.openqa.selenium.support.PageFactory; 15 | import org.openqa.selenium.support.ui.ExpectedConditions; 16 | import org.openqa.selenium.support.ui.WebDriverWait; 17 | 18 | import java.time.Duration; 19 | 20 | public class MainPageWithFindBy extends SeleniumBasePage { 21 | 22 | @FindBy(id = "markup-generation-button") 23 | WebElement generateMarkupBtnId; 24 | 25 | @FindBy(xpath = "//button[@id='submit_alert']") 26 | WebElement testButton; 27 | 28 | @FindBy(id = "for-invisible-test") 29 | WebElement buttonForInvisible; 30 | 31 | @FindBy(id = "field-parent") 32 | WebElement fieldParent; 33 | 34 | @FindBy(id = "change_id") 35 | WebElement inputFieldChangeID; 36 | 37 | 38 | @FindBy(id = "Submit") 39 | WebElement submitButton; 40 | 41 | @FindBy(className = "test_class") 42 | WebElement inputFieldChangeClassName; 43 | 44 | @FindBy(xpath ="//test_tag/following-sibling::input") 45 | WebElement inputFieldChangeTagName; 46 | 47 | @FindBy (name = "change_name") 48 | WebElement inputFieldChangeName; 49 | @FindBy (linkText = "Change: LinkText, PartialLinkText") 50 | WebElement inputFieldChangeLinkText; 51 | 52 | @FindBy(id = "form_checked1") 53 | WebElement checkBox1; 54 | 55 | @FindBy(id = "form_checked2") 56 | WebElement checkBox2; 57 | 58 | @FindBy(id = "form_checked3") 59 | WebElement checkBox3; 60 | 61 | @FindBy(id = "Submit_checkbox") 62 | WebElement submitButton1; 63 | 64 | @FindBy(id = "change_enabled") 65 | WebElement InputFieldEnableTODisable; 66 | 67 | @FindBy(id = "change_checked") 68 | WebElement checkBoxEnableToDisable; 69 | 70 | public MainPageWithFindBy(WebDriver driver) { 71 | super(driver); 72 | PageFactory.initElements(driver, this); 73 | } 74 | 75 | @Step("Open Main page") 76 | public MainPageWithFindBy openPage() { 77 | driver.get(mainPageUrl); 78 | return this; 79 | } 80 | 81 | @Step("Generate markup") 82 | public MainPageWithFindBy generateMarkup() { 83 | generateMarkupBtnId.click(); 84 | return this; 85 | } 86 | 87 | @Step("Click test button") 88 | public MainPageWithFindBy clickTestButton() { 89 | testButton.click(); 90 | return this; 91 | } 92 | 93 | public MainPageWithFindBy clickButtonForInvisible() { 94 | buttonForInvisible.click(); 95 | return this; 96 | } 97 | 98 | public boolean checkThatButtonInvisible() { 99 | try { 100 | new WebDriverWait(driver, Duration.ofSeconds(1)) 101 | .until(ExpectedConditions.invisibilityOf(buttonForInvisible)); 102 | return true; 103 | } catch (Exception e) { 104 | return false; 105 | } 106 | } 107 | 108 | public MainPageWithFindBy hoverOnTestButton() { 109 | Actions action = new Actions(driver); 110 | action.moveToElement(testButton).perform(); 111 | return this; 112 | } 113 | 114 | public String takeValueFromSecondButton() { 115 | return fieldParent 116 | .findElement(By.xpath(".//input")) 117 | .getAttribute("Value"); 118 | } 119 | 120 | public String getAttributeFromTestButton(String attribute) { 121 | return testButton.getAttribute(attribute); 122 | } 123 | 124 | @DisableHealing 125 | public boolean checkLocatorTestButtonDontHealing() { 126 | try { 127 | testButton.click(); 128 | return false; 129 | } catch (NoSuchElementException e) { 130 | return true; 131 | } 132 | } 133 | 134 | @Step("Find and click InputFiled for Change ID") 135 | public MainPageWithFindBy clickElementByChangeID() { 136 | inputFieldChangeID.click(); 137 | return this; 138 | } 139 | 140 | public MainPageWithFindBy clickSubmitButton() { 141 | submitButton.click(); 142 | return this; 143 | } 144 | 145 | public MainPageWithFindBy clickElementByChangeClassName(){ 146 | inputFieldChangeClassName.click(); 147 | return this; 148 | } 149 | 150 | public MainPageWithFindBy clickElementByChangeTagName() { 151 | inputFieldChangeTagName.click(); 152 | return this; 153 | } 154 | 155 | public MainPageWithFindBy clickElementByChangeName() { 156 | inputFieldChangeName.click(); 157 | return this; 158 | } 159 | 160 | public MainPageWithFindBy findElementByChangeLinkText() { 161 | inputFieldChangeLinkText.isDisplayed(); 162 | return this; 163 | } 164 | 165 | public MainPageWithFindBy findCheckBox1() { 166 | checkBox1.isDisplayed(); 167 | return this; 168 | } 169 | 170 | public MainPageWithFindBy findCheckBox2() { 171 | checkBox2.isDisplayed(); 172 | return this; 173 | } 174 | 175 | public MainPageWithFindBy findCheckBox3() { 176 | checkBox3.isDisplayed(); 177 | return this; 178 | } 179 | 180 | public MainPageWithFindBy clickSubmitButtonForCheckBox() { 181 | submitButton1.click(); 182 | return this; 183 | } 184 | 185 | public MainPageWithFindBy findElementEnableToDisable() { 186 | InputFieldEnableTODisable.isDisplayed(); 187 | return this; 188 | } 189 | 190 | public MainPageWithFindBy findCheckBoxEnableToDisable() { 191 | checkBoxEnableToDisable.isDisplayed(); 192 | return this; 193 | } 194 | 195 | } 196 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/pageobject/markup/MarkupPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.pageobject.markup; 2 | 3 | import com.epam.healenium.annotation.DisableHealing; 4 | import com.epam.healenium.selenium.pageobject.SeleniumBasePage; 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.NoSuchElementException; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.WebElement; 9 | import org.openqa.selenium.support.ui.ExpectedConditions; 10 | import org.openqa.selenium.support.ui.WebDriverWait; 11 | 12 | import java.time.Duration; 13 | import java.util.List; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertTrue; 16 | 17 | public class MarkupPage extends SeleniumBasePage { 18 | 19 | private By generateMarkupBtnId = By.id("markup-generation-button"); 20 | private By testButton = By.className("default-btn"); 21 | private By testGeneratedButton = By.id("random-id"); 22 | 23 | private By checkboxAccount = By.xpath("//*[@class='checkbox checkbox_size_m checkbox_theme_alfa-on-white']"); 24 | private By textFirstSelect = By.xpath("(//*[text()='Select Account'])[1]"); 25 | 26 | private By firstCheckboxChecked = By.xpath("//*[text()='Current account']//parent::label[contains(@class,'checked')]"); 27 | private By checkboxChecked = By.xpath("//label[contains(@class,'checkbox_checked')]"); 28 | private By checkboxUnchecked = By.xpath("//label[not(contains(@class,'checkbox_checked'))]"); 29 | 30 | private By parentInput = By.xpath("//*[contains(@class,'input-group') and @role='group']");//span[@class='input__box']"); 31 | private By childInput = By.xpath(".//*[@value='']"); 32 | 33 | public MarkupPage(WebDriver driver) { 34 | super(driver); 35 | } 36 | 37 | public MarkupPage openPage() { 38 | driver.get(mainPageUrl); 39 | return this; 40 | } 41 | 42 | public MarkupPage generateMarkup() { 43 | driver.findElement(generateMarkupBtnId).click(); 44 | return this; 45 | } 46 | 47 | public MarkupPage clickTestButton() { 48 | driver.findElement(testButton).click(); 49 | return this; 50 | } 51 | 52 | public MarkupPage clickTestGeneratedButton() { 53 | driver.findElement(testGeneratedButton).click(); 54 | return this; 55 | } 56 | 57 | @DisableHealing 58 | public boolean displayedText() { 59 | try { 60 | return driver.findElement(textFirstSelect).isEnabled(); 61 | } catch (NoSuchElementException e1) { 62 | return false; 63 | } 64 | } 65 | 66 | public MarkupPage selectFirstCheckbox() { 67 | driver.findElements(checkboxAccount).get(0).click(); 68 | return this; 69 | } 70 | 71 | public boolean verifyFirstCheckbox() { 72 | return driver.findElements(checkboxAccount).get(0).isEnabled(); 73 | } 74 | 75 | @DisableHealing 76 | public int verifyAllCheckboxesChecked() { 77 | List checkboxes = driver.findElements(checkboxChecked); 78 | checkboxes.forEach(c -> assertTrue(c.isEnabled())); 79 | return checkboxes.size(); 80 | } 81 | 82 | @DisableHealing 83 | public int verifyAllCheckboxesUnchecked() { 84 | List checkboxes = driver.findElements(checkboxUnchecked); 85 | checkboxes.forEach(c -> assertTrue(c.isEnabled())); 86 | return checkboxes.size(); 87 | } 88 | 89 | public int selectAllCheckboxes() { 90 | List checkboxes = driver.findElements(checkboxAccount); 91 | if (checkboxes.size() == 0) 92 | throw new NoSuchElementException("No checkboxes found"); 93 | checkboxes.forEach(c -> c.click()); 94 | return checkboxes.size(); 95 | } 96 | 97 | public boolean verifyFirstAccountCheckbox() { 98 | return driver.findElement(firstCheckboxChecked).isEnabled(); 99 | } 100 | 101 | public MarkupPage selectFirstAccountCheckbox() { 102 | driver.findElement(firstCheckboxChecked).click(); 103 | return this; 104 | } 105 | 106 | @DisableHealing 107 | public boolean testButtonEnable() { 108 | try { 109 | return driver.findElement(testGeneratedButton).isEnabled(); 110 | } catch (NoSuchElementException e) { 111 | return false; 112 | } 113 | } 114 | 115 | @DisableHealing 116 | public boolean groupInputEnabled() { 117 | try { 118 | return driver.findElement(parentInput).isEnabled() 119 | && driver.findElement(By.xpath("//*[@placeholder='Just some text']")) 120 | .isEnabled(); 121 | } catch (NoSuchElementException e1) { 122 | return false; 123 | } 124 | } 125 | 126 | @DisableHealing 127 | public void fillInputsGroup() { 128 | WebElement parent = driver.findElement(parentInput); 129 | List child = parent.findElements(childInput); 130 | child.forEach(c -> c.sendKeys("Value")); 131 | } 132 | 133 | public void verifyInputText() { 134 | WebElement parent = driver.findElement(parentInput); 135 | List child = parent.findElements(childInput); 136 | if (child.size() == 0) 137 | throw new NoSuchElementException("No inputs found"); 138 | child.forEach(c -> assertTrue(c.isEnabled())); 139 | } 140 | 141 | public MarkupPage clickTestButtonWaitor(int seconds) { 142 | 143 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(seconds)); 144 | wait.until(ExpectedConditions.elementToBeClickable(testButton)).click(); 145 | 146 | return this; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/pageobject/testenv/TestEnvPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.pageobject.testenv; 2 | 3 | import com.epam.healenium.constants.LocatorType; 4 | import com.epam.healenium.constants.PageUrl; 5 | import com.epam.healenium.selenium.pageobject.SeleniumBasePage; 6 | import com.epam.healenium.selenium.search.Context; 7 | import org.openqa.selenium.By; 8 | import org.openqa.selenium.WebDriver; 9 | import org.openqa.selenium.WebElement; 10 | 11 | import java.util.List; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertTrue; 14 | 15 | public class TestEnvPage extends SeleniumBasePage { 16 | 17 | private By submitButton = By.id("Submit"); 18 | private By formButton = By.id("Submit_checkbox"); 19 | 20 | public TestEnvPage(WebDriver driver) { 21 | super(driver); 22 | } 23 | 24 | public TestEnvPage openPage() { 25 | driver.get(PageUrl.TEST_ENV_URL.toString()); 26 | return this; 27 | } 28 | 29 | public TestEnvPage findTestElement(LocatorType type, String selector) { 30 | boolean result = new Context(driver, type).executeStrategy(selector); 31 | assertTrue(result); 32 | return this; 33 | } 34 | 35 | public TestEnvPage clickSubmitButton() { 36 | driver.findElement(submitButton).click(); 37 | return this; 38 | } 39 | 40 | public TestEnvPage findElementsUnderParent(String parentXpath, String childXpath) { 41 | List formElements = driver.findElement(By.xpath(parentXpath)).findElements(By.xpath("." + childXpath)); 42 | formElements.forEach(f -> f.click()); 43 | return this; 44 | } 45 | 46 | public TestEnvPage clickFormButton(){ 47 | driver.findElement(formButton).click(); 48 | return this; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/Context.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search; 2 | 3 | import com.epam.healenium.constants.LocatorType; 4 | import com.epam.healenium.selenium.search.locators.*; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class Context { 8 | private Strategy strategy; 9 | 10 | public Context(WebDriver driver, LocatorType type) { 11 | switch (type) { 12 | case XPATH: 13 | this.strategy = new XPathStrategy(driver); 14 | break; 15 | case CSS: 16 | this.strategy = new CssStrategy(driver); 17 | break; 18 | case ID: 19 | this.strategy = new IdStrategy(driver); 20 | break; 21 | case CLASS_NAME: 22 | this.strategy = new ClassNameStrategy(driver); 23 | break; 24 | case LINK_TEXT: 25 | this.strategy = new LinkTextStrategy(driver); 26 | break; 27 | case PARTIAL_LINK_TEXT: 28 | this.strategy = new PartialLinkStrategy(driver); 29 | break; 30 | case TAG_NAME: 31 | this.strategy = new TagStrategy(driver); 32 | break; 33 | case NAME: 34 | this.strategy = new NameStrategy(driver); 35 | break; 36 | } 37 | } 38 | 39 | public boolean executeStrategy(String selector) { 40 | return strategy.doAction(selector); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/Strategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search; 2 | 3 | public interface Strategy { 4 | boolean doAction(String selector); 5 | } -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/locators/ClassNameStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search.locators; 2 | 3 | import com.epam.healenium.selenium.search.Strategy; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class ClassNameStrategy implements Strategy { 8 | private WebDriver driver; 9 | 10 | public ClassNameStrategy(WebDriver driver) { 11 | this.driver = driver; 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return driver.findElement(By.className(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/locators/CssStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search.locators; 2 | 3 | import com.epam.healenium.selenium.search.Strategy; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class CssStrategy implements Strategy { 8 | private WebDriver driver; 9 | 10 | public CssStrategy(WebDriver driver) { 11 | this.driver = driver; 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return driver.findElement(By.cssSelector(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/locators/IdStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search.locators; 2 | 3 | import com.epam.healenium.selenium.search.Strategy; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class IdStrategy implements Strategy { 8 | private WebDriver driver; 9 | 10 | public IdStrategy(WebDriver driver) { 11 | this.driver = driver; 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return driver.findElement(By.id(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/locators/LinkTextStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search.locators; 2 | 3 | import com.epam.healenium.selenium.search.Strategy; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class LinkTextStrategy implements Strategy { 8 | private WebDriver driver; 9 | 10 | public LinkTextStrategy(WebDriver driver) { 11 | this.driver = driver; 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return driver.findElement(By.linkText(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/locators/NameStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search.locators; 2 | 3 | import com.epam.healenium.selenium.search.Strategy; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class NameStrategy implements Strategy { 8 | private WebDriver driver; 9 | 10 | public NameStrategy(WebDriver driver) { 11 | this.driver = driver; 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return driver.findElement(By.name(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/locators/PartialLinkStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search.locators; 2 | 3 | import com.epam.healenium.selenium.search.Strategy; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class PartialLinkStrategy implements Strategy { 8 | private WebDriver driver; 9 | 10 | public PartialLinkStrategy(WebDriver driver) { 11 | this.driver = driver; 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return driver.findElement(By.partialLinkText(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/locators/TagStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search.locators; 2 | 3 | import com.epam.healenium.selenium.search.Strategy; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class TagStrategy implements Strategy { 8 | private WebDriver driver; 9 | 10 | public TagStrategy(WebDriver driver) { 11 | this.driver = driver; 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return driver.findElement(By.tagName(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/selenium/search/locators/XPathStrategy.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.selenium.search.locators; 2 | 3 | import com.epam.healenium.selenium.search.Strategy; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | 7 | public class XPathStrategy implements Strategy { 8 | private WebDriver driver; 9 | 10 | public XPathStrategy(WebDriver driver) { 11 | this.driver=driver; 12 | } 13 | 14 | @Override 15 | public boolean doAction(String selector) { 16 | return driver.findElement(By.xpath(selector)).isDisplayed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/DriverContext.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings; 2 | 3 | import com.epam.healenium.constants.BrowserType; 4 | import com.epam.healenium.constants.DriverType; 5 | import com.epam.healenium.settings.drivers.LocalDriver; 6 | import com.epam.healenium.settings.drivers.ProxyDriver; 7 | import com.epam.healenium.settings.drivers.RemoteDriver; 8 | import org.openqa.selenium.WebDriver; 9 | 10 | import java.net.MalformedURLException; 11 | 12 | public class DriverContext { 13 | 14 | private WebDriver driver; 15 | private IDriverInterface context; 16 | 17 | public DriverContext(DriverType local) { 18 | switch (local) { 19 | case LOCAL: 20 | this.context = new LocalDriver(); 21 | break; 22 | case PROXY: 23 | this.context = new ProxyDriver(); 24 | break; 25 | case REMOTE: 26 | this.context = new RemoteDriver(); 27 | break; 28 | } 29 | 30 | } 31 | 32 | public WebDriver getDriver(BrowserType browser) throws MalformedURLException { 33 | switch (browser) { 34 | case CHROME: 35 | this.driver = context.setDriver(context.useChrome()); 36 | break; 37 | case FIREFOX: 38 | this.driver = context.setDriver(context.useFirefox()); 39 | break; 40 | case IE: 41 | this.driver = context.setDriver(context.useEdge()); 42 | break; 43 | case SAFARI: 44 | this.driver = context.setDriver(context.useSafari()); 45 | break; 46 | } 47 | return this.driver; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/FrameworkContext.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import com.epam.healenium.constants.FrameworkType; 5 | import com.epam.healenium.constants.PagesType; 6 | import com.epam.healenium.settings.framework.JdiContext; 7 | import com.epam.healenium.settings.framework.SelenideContext; 8 | import com.epam.healenium.settings.framework.SeleniumContext; 9 | import org.openqa.selenium.WebDriver; 10 | 11 | import java.util.HashMap; 12 | 13 | public class FrameworkContext { 14 | 15 | private IFrameworkInterface type; 16 | 17 | public FrameworkContext(FrameworkType type, WebDriver driver) { 18 | switch (type) { 19 | case SELENIUM: 20 | this.type = new SeleniumContext(driver); 21 | break; 22 | case SELENIDE: 23 | this.type = new SelenideContext(driver); 24 | break; 25 | case JDI: 26 | this.type = new JdiContext(driver); 27 | break; 28 | default: 29 | break; 30 | } 31 | } 32 | 33 | public HashMap setFramework() { 34 | return this.type.useSettings(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/IDriverInterface.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | 5 | import java.net.MalformedURLException; 6 | 7 | public interface IDriverInterface { 8 | 9 | static final String LOCALHOST = "localhost"; 10 | static final String SELENOID = "10.6.223.91"; 11 | 12 | WebDriver setDriver(Object delegate) throws MalformedURLException; 13 | 14 | Object useChrome(); 15 | 16 | Object useFirefox(); 17 | 18 | Object useEdge(); 19 | 20 | Object useSafari(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/IFrameworkInterface.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import com.epam.healenium.constants.PagesType; 5 | 6 | import java.util.HashMap; 7 | 8 | public interface IFrameworkInterface { 9 | HashMap useSettings(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/drivers/LocalDriver.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings.drivers; 2 | 3 | import com.epam.healenium.SelfHealingDriver; 4 | import com.epam.healenium.settings.IDriverInterface; 5 | import io.github.bonigarcia.wdm.WebDriverManager; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | import org.openqa.selenium.chrome.ChromeOptions; 9 | import org.openqa.selenium.edge.EdgeDriver; 10 | import org.openqa.selenium.edge.EdgeOptions; 11 | import org.openqa.selenium.firefox.FirefoxDriver; 12 | import org.openqa.selenium.firefox.FirefoxOptions; 13 | import org.openqa.selenium.safari.SafariDriver; 14 | import org.openqa.selenium.safari.SafariOptions; 15 | 16 | public class LocalDriver implements IDriverInterface { 17 | private SelfHealingDriver driver; 18 | 19 | @Override 20 | public WebDriver setDriver(Object delegate) { 21 | driver = SelfHealingDriver.create((WebDriver) delegate); 22 | 23 | return driver; 24 | } 25 | 26 | @Override 27 | public Object useChrome() { 28 | WebDriverManager.chromedriver().setup(); 29 | ChromeOptions options = new ChromeOptions(); 30 | options.addArguments("--user-data-dir=/tmp/unique-chrome-profile-" + System.currentTimeMillis()); 31 | options.addArguments("--headless"); // Запуск в headless-режиме 32 | options.addArguments("--disable-gpu"); 33 | options.addArguments("--no-sandbox"); 34 | WebDriver delegate = new ChromeDriver(options); 35 | return delegate; 36 | } 37 | 38 | @Override 39 | public Object useFirefox() { 40 | WebDriverManager.firefoxdriver().setup(); 41 | FirefoxOptions options = new FirefoxOptions(); 42 | // options.setHeadless(false); 43 | 44 | WebDriver delegate = new FirefoxDriver(options); 45 | return delegate; 46 | } 47 | 48 | @Override 49 | public Object useEdge() { 50 | WebDriverManager.edgedriver().setup(); 51 | EdgeOptions options = new EdgeOptions(); 52 | 53 | WebDriver delegate = new EdgeDriver(options); 54 | return delegate; 55 | } 56 | 57 | @Override 58 | public Object useSafari() { 59 | SafariOptions options = new SafariOptions(); 60 | 61 | WebDriver delegate = new SafariDriver(options); 62 | return delegate; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/drivers/ProxyDriver.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings.drivers; 2 | 3 | import com.epam.healenium.settings.IDriverInterface; 4 | import org.openqa.selenium.Capabilities; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.chrome.ChromeOptions; 7 | import org.openqa.selenium.edge.EdgeOptions; 8 | import org.openqa.selenium.firefox.FirefoxOptions; 9 | import org.openqa.selenium.remote.RemoteWebDriver; 10 | import org.openqa.selenium.safari.SafariOptions; 11 | 12 | import java.net.MalformedURLException; 13 | import java.net.URL; 14 | 15 | public class ProxyDriver implements IDriverInterface { 16 | private RemoteWebDriver driver; 17 | 18 | @Override 19 | public WebDriver setDriver(Object options) throws MalformedURLException { 20 | this.driver = new RemoteWebDriver(new URL("http://" + LOCALHOST + ":8085"), (Capabilities) options); 21 | return this.driver; 22 | } 23 | 24 | @Override 25 | public Object useChrome() { 26 | ChromeOptions options = new ChromeOptions(); 27 | return options; 28 | } 29 | 30 | @Override 31 | public Object useFirefox() { 32 | FirefoxOptions options = new FirefoxOptions(); 33 | return options; 34 | } 35 | 36 | @Override 37 | public Object useSafari() { 38 | SafariOptions options = new SafariOptions(); 39 | return options; 40 | } 41 | 42 | @Override 43 | public Object useEdge() { 44 | EdgeOptions options = new EdgeOptions(); 45 | options.addArguments("--no-sandbox"); 46 | options.addArguments("--disable-dev-shm-usage"); 47 | 48 | return options; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/drivers/RemoteDriver.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings.drivers; 2 | 3 | import com.epam.healenium.SelfHealingDriver; 4 | import com.epam.healenium.settings.IDriverInterface; 5 | import org.openqa.selenium.Capabilities; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.remote.DesiredCapabilities; 8 | import org.openqa.selenium.remote.RemoteWebDriver; 9 | 10 | import java.net.MalformedURLException; 11 | import java.net.URI; 12 | 13 | public class RemoteDriver implements IDriverInterface { 14 | 15 | private SelfHealingDriver driver; 16 | 17 | @Override 18 | public WebDriver setDriver(Object capabilities) throws MalformedURLException { 19 | RemoteWebDriver delegate = new RemoteWebDriver( 20 | URI.create("http://" + SELENOID + ":4444/wd/hub").toURL(), 21 | (Capabilities) capabilities 22 | ); 23 | this.driver = SelfHealingDriver.create(delegate); 24 | 25 | return this.driver; 26 | } 27 | 28 | @Override 29 | public Object useChrome() { 30 | DesiredCapabilities capabilities = new DesiredCapabilities(); 31 | capabilities.setCapability("browserName", "chrome"); 32 | capabilities.setCapability("enableVNC", true); 33 | 34 | return capabilities; 35 | } 36 | 37 | @Override 38 | public Object useFirefox() { 39 | DesiredCapabilities capabilities = new DesiredCapabilities(); 40 | capabilities.setCapability("browserName", "firefox"); 41 | capabilities.setCapability("enableVNC", true); 42 | 43 | return capabilities; 44 | } 45 | 46 | @Override 47 | public Object useEdge() { 48 | DesiredCapabilities capabilities = new DesiredCapabilities(); 49 | capabilities.setCapability("browserName", "edge"); 50 | capabilities.setCapability("enableVNC", true); 51 | 52 | return capabilities; 53 | } 54 | 55 | @Override 56 | public Object useSafari() { 57 | DesiredCapabilities capabilities = new DesiredCapabilities(); 58 | capabilities.setCapability("browserName", "safari"); 59 | capabilities.setCapability("enableVNC", true); 60 | 61 | return capabilities; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/framework/JdiContext.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings.framework; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import com.epam.healenium.constants.PagesType; 5 | import com.epam.healenium.settings.IFrameworkInterface; 6 | import org.openqa.selenium.WebDriver; 7 | 8 | import java.util.HashMap; 9 | 10 | public class JdiContext implements IFrameworkInterface { 11 | private WebDriver driver; 12 | 13 | public JdiContext(WebDriver driver) { 14 | this.driver = driver; 15 | } 16 | 17 | @Override 18 | public HashMap useSettings() { 19 | return null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/framework/SelenideContext.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings.framework; 2 | 3 | import com.codeborne.selenide.WebDriverRunner; 4 | import com.epam.healenium.FrameworkPage; 5 | import com.epam.healenium.constants.PagesType; 6 | import com.epam.healenium.selenide.pageobject.markup.SelenideMainPageWithFindBy; 7 | import com.epam.healenium.selenide.pageobject.markup.SelenideMarkupPage; 8 | import com.epam.healenium.selenide.pageobject.callback.SelenideCallbackPage; 9 | import com.epam.healenium.selenide.pageobject.testenv.SelenideTestEnvPage; 10 | import com.epam.healenium.settings.IFrameworkInterface; 11 | import org.openqa.selenium.WebDriver; 12 | 13 | import java.util.HashMap; 14 | 15 | import static com.epam.healenium.constants.PagesType.CALLBACK; 16 | import static com.epam.healenium.constants.PagesType.MARKUP; 17 | import static com.epam.healenium.constants.PagesType.MARKUP_FIND_BY; 18 | import static com.epam.healenium.constants.PagesType.TEST_ENV; 19 | 20 | public class SelenideContext implements IFrameworkInterface { 21 | 22 | public SelenideContext(WebDriver driver) { 23 | WebDriverRunner.setWebDriver(driver); 24 | } 25 | 26 | @Override 27 | public HashMap useSettings() { 28 | HashMap selenideContext = new HashMap<>(); 29 | 30 | selenideContext.put(TEST_ENV, new SelenideTestEnvPage()); 31 | selenideContext.put(CALLBACK, new SelenideCallbackPage()); 32 | selenideContext.put(MARKUP, new SelenideMarkupPage()); 33 | selenideContext.put(MARKUP_FIND_BY, new SelenideMainPageWithFindBy()); 34 | 35 | return selenideContext; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/epam/healenium/settings/framework/SeleniumContext.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.settings.framework; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import com.epam.healenium.constants.PagesType; 5 | import com.epam.healenium.selenium.pageobject.callback.CallbackPage; 6 | import com.epam.healenium.selenium.pageobject.markup.MainPageWithFindBy; 7 | import com.epam.healenium.selenium.pageobject.markup.MarkupPage; 8 | import com.epam.healenium.selenium.pageobject.testenv.TestEnvPage; 9 | import com.epam.healenium.settings.IFrameworkInterface; 10 | import org.openqa.selenium.WebDriver; 11 | 12 | import java.util.HashMap; 13 | 14 | import static com.epam.healenium.constants.PagesType.CALLBACK; 15 | import static com.epam.healenium.constants.PagesType.MARKUP; 16 | import static com.epam.healenium.constants.PagesType.MARKUP_FIND_BY; 17 | import static com.epam.healenium.constants.PagesType.TEST_ENV; 18 | 19 | public class SeleniumContext implements IFrameworkInterface { 20 | private WebDriver driver; 21 | 22 | public SeleniumContext(WebDriver driver) { 23 | this.driver = driver; 24 | } 25 | 26 | @Override 27 | public HashMap useSettings() { 28 | HashMap seleniumContext = new HashMap<>(); 29 | seleniumContext.put(TEST_ENV, new TestEnvPage(this.driver)); 30 | seleniumContext.put(MARKUP, new MarkupPage(this.driver)); 31 | seleniumContext.put(MARKUP_FIND_BY, new MainPageWithFindBy(this.driver)); 32 | seleniumContext.put(CALLBACK, new CallbackPage(this.driver)); 33 | 34 | return seleniumContext; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/epam/healenium/tests/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.tests; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import com.epam.healenium.constants.BrowserType; 5 | import com.epam.healenium.constants.DriverType; 6 | import com.epam.healenium.constants.FrameworkType; 7 | import com.epam.healenium.constants.PagesType; 8 | import com.epam.healenium.settings.DriverContext; 9 | import com.epam.healenium.settings.FrameworkContext; 10 | import org.junit.jupiter.api.AfterAll; 11 | import org.junit.jupiter.api.BeforeAll; 12 | import org.openqa.selenium.Dimension; 13 | import org.openqa.selenium.WebDriver; 14 | 15 | import java.net.MalformedURLException; 16 | import java.util.HashMap; 17 | 18 | public class BaseTest { 19 | static protected WebDriver driver; 20 | static protected HashMap pages; 21 | 22 | @BeforeAll 23 | static public void setUp() throws MalformedURLException { 24 | driver = new DriverContext(DriverType.LOCAL).getDriver(BrowserType.CHROME); 25 | 26 | driver.manage().window().setSize(new Dimension(1200, 800)); 27 | 28 | pages = new FrameworkContext(FrameworkType.SELENIUM, driver).setFramework(); 29 | } 30 | 31 | @AfterAll 32 | static public void afterAll() { 33 | if (driver != null) { 34 | driver.quit(); 35 | } 36 | } 37 | 38 | // @Attachment(value = "Screenshot", type = "image/png") 39 | // public byte[] screenshot() { 40 | // return ((TakesScreenshot) ((SelfHealingDriver) driver).getDelegate()).getScreenshotAs(OutputType.BYTES); 41 | // } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/epam/healenium/tests/CssTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.tests; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import io.qameta.allure.Description; 5 | import io.qameta.allure.Severity; 6 | import io.qameta.allure.SeverityLevel; 7 | import org.junit.jupiter.api.Test; 8 | import org.openqa.selenium.By; 9 | 10 | import static com.epam.healenium.constants.PagesType.CALLBACK; 11 | import static com.epam.healenium.constants.PagesType.TEST_ENV; 12 | import static org.junit.jupiter.api.Assertions.assertTrue; 13 | 14 | public class CssTest extends BaseTest { 15 | 16 | @Test 17 | @Severity(SeverityLevel.NORMAL) 18 | @Description("Update locator for element with css attribute") 19 | public void testCssAttribute() { 20 | FrameworkPage callbackTestPage = pages.get(CALLBACK); 21 | 22 | boolean result = callbackTestPage 23 | .openPage() 24 | .clickAddSquareButton() 25 | .verifySquareElement(); 26 | assertTrue(result, "Element with css enabled"); 27 | 28 | for (int i = 0; i <= 2; i++) { 29 | result = callbackTestPage 30 | .clickUpdateSquareButton() 31 | .verifySquareElement(); //should be healed 32 | assertTrue(result, "Element with css was healed"); 33 | } 34 | } 35 | 36 | @Test 37 | @Severity(SeverityLevel.NORMAL) 38 | @Description("Update locator for element with css id") 39 | public void testCssId() { 40 | FrameworkPage page = pages.get(TEST_ENV); 41 | 42 | page.openPage(); 43 | driver.findElement(By.cssSelector("#change_id")); 44 | page.clickSubmitButton(); 45 | driver.findElement(By.cssSelector("#change_id")); 46 | } 47 | 48 | @Test 49 | @Severity(SeverityLevel.NORMAL) 50 | @Description("Update locator for element with css id with special character") 51 | public void testCssIdSpecialCharacter() { 52 | FrameworkPage page = pages.get(TEST_ENV); 53 | 54 | page.openPage(); 55 | driver.findElement(By.cssSelector("input#change\\:name")); 56 | page.clickSubmitButton(); 57 | driver.findElement(By.cssSelector("input#change\\:name")); 58 | } 59 | 60 | @Test 61 | @Severity(SeverityLevel.NORMAL) 62 | @Description("Update locator for element with css Element") 63 | public void testCssElement() { 64 | FrameworkPage page = pages.get(TEST_ENV); 65 | 66 | page.openPage(); 67 | driver.findElement(By.cssSelector("test_tag")).isDisplayed(); 68 | page.clickSubmitButton(); 69 | driver.findElement(By.cssSelector("test_tag")).isDisplayed(); 70 | } 71 | 72 | @Test 73 | @Severity(SeverityLevel.NORMAL) 74 | @Description("Update locator for element with css Disabled") 75 | public void testCssDisabled() { 76 | FrameworkPage page = pages.get(TEST_ENV); 77 | 78 | page.openPage(); 79 | driver.findElement(By.cssSelector("input:disabled")); 80 | page.clickSubmitButton(); 81 | driver.findElement(By.cssSelector("input:disabled")); 82 | } 83 | 84 | @Test 85 | @Severity(SeverityLevel.NORMAL) 86 | @Description("Update locator for element with css Enabled") 87 | public void testCssEnabled() { 88 | FrameworkPage page = pages.get(TEST_ENV); 89 | 90 | page.openPage(); 91 | driver.findElement(By.cssSelector("textarea:enabled")); 92 | page.clickSubmitButton(); 93 | driver.findElement(By.cssSelector("textarea:enabled")); 94 | } 95 | 96 | @Test 97 | @Severity(SeverityLevel.NORMAL) 98 | @Description("Update locator for element with css Checked") 99 | public void testCssChecked() { 100 | FrameworkPage page = pages.get(TEST_ENV); 101 | 102 | page.openPage(); 103 | driver.findElement(By.cssSelector("input:checked")); 104 | page.clickSubmitButton(); 105 | driver.findElement(By.cssSelector("input:checked")); 106 | } 107 | 108 | @Test 109 | @Severity(SeverityLevel.NORMAL) 110 | @Description("Update locator for element with css Hover") 111 | public void testCssHover() { 112 | 113 | } 114 | 115 | @Test 116 | @Severity(SeverityLevel.NORMAL) 117 | @Description("Update locator for element with css ClassName") 118 | public void testCssClassName() { 119 | FrameworkPage page = pages.get(TEST_ENV); 120 | 121 | page.openPage(); 122 | driver.findElement(By.cssSelector(".test_class")); 123 | page.clickSubmitButton(); 124 | driver.findElement(By.cssSelector(".test_class")); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/test/java/com/epam/healenium/tests/GeneralTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.tests; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import com.epam.healenium.constants.PagesType; 5 | import com.epam.healenium.selenide.pageobject.SelenideBasePage; 6 | import com.epam.healenium.selenide.pageobject.markup.SelenideMarkupPage; 7 | import io.qameta.allure.Description; 8 | import io.qameta.allure.Severity; 9 | import io.qameta.allure.SeverityLevel; 10 | import org.junit.jupiter.api.Assertions; 11 | import org.junit.jupiter.api.Test; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertTrue; 14 | 15 | public class GeneralTest extends BaseTest { 16 | @Test 17 | @Severity(SeverityLevel.NORMAL) 18 | @Description("Button click with FindBy annotation") 19 | public void testButtonClickWithFindByAnnotationPage() { 20 | FrameworkPage mainPage = pages.get(PagesType.MARKUP_FIND_BY); 21 | 22 | mainPage.openPage().clickTestButton() 23 | .confirmAlert() 24 | .clickElementByChangeID(); // Click Element By Change ID 25 | mainPage.clickSubmitButton() //clicking Change locators button 26 | .clickElementByChangeID(); 27 | } 28 | 29 | @Test 30 | @Severity(SeverityLevel.NORMAL) 31 | @Description("Input fields click with FindBy annotation") 32 | public void testInputFiledsWithFindByAnnotationPage(){ 33 | FrameworkPage mainPage = pages.get(PagesType.MARKUP_FIND_BY); 34 | 35 | mainPage.openPage().clickElementByChangeClassName() 36 | .clickElementByChangeTagName() 37 | .clickElementByChangeName() 38 | .findElementByChangeLinkText(); 39 | mainPage.clickSubmitButton() 40 | .clickElementByChangeClassName() 41 | .clickElementByChangeTagName() 42 | .clickElementByChangeName() 43 | .findElementByChangeLinkText(); 44 | } 45 | 46 | @Test 47 | @Severity(SeverityLevel.NORMAL) 48 | @Description("check box verify with FindBy annotation") 49 | public void checkBoxWithFinByAnnotoationPage() { 50 | FrameworkPage mainPage = pages.get(PagesType.MARKUP_FIND_BY); 51 | 52 | mainPage.openPage().findCheckBox1() 53 | .findCheckBox2() 54 | .findCheckBox3(); 55 | mainPage.clickSubmitButtonForCheckBox() 56 | .findCheckBox1() 57 | .findCheckBox2() 58 | .findCheckBox3(); 59 | } 60 | 61 | 62 | @Test 63 | @Severity(SeverityLevel.NORMAL) 64 | @Description("Input field enable to disable with FindBy annoatation ") 65 | public void testInputFieldEnableToDisableWithFindByAnnotationPage() { 66 | FrameworkPage mainPage = pages.get(PagesType.MARKUP_FIND_BY); 67 | 68 | mainPage.openPage().findElementEnableToDisable(); 69 | mainPage.clickSubmitButton() 70 | .findElementEnableToDisable(); 71 | } 72 | 73 | @Test 74 | @Severity(SeverityLevel.NORMAL) 75 | @Description ("check box checked to unchecked with FindBy Annotation") 76 | public void testCheckBoxCheckedToUncheckWithFindByAnnotationPage() { 77 | 78 | FrameworkPage mainPage = pages.get(PagesType.MARKUP_FIND_BY); 79 | mainPage.openPage().findCheckBoxEnableToDisable(); 80 | mainPage.clickSubmitButton() 81 | .findCheckBoxEnableToDisable(); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/test/java/com/epam/healenium/tests/ParentChildTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.tests; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import io.qameta.allure.Description; 5 | import io.qameta.allure.Severity; 6 | import io.qameta.allure.SeverityLevel; 7 | import org.junit.jupiter.api.Test; 8 | import org.openqa.selenium.By; 9 | 10 | import static com.epam.healenium.constants.PagesType.TEST_ENV; 11 | 12 | public class ParentChildTest extends BaseTest { 13 | 14 | // @Test 15 | // @Severity(SeverityLevel.MINOR) 16 | // @Description("Select first checkbox and verify using parent:: function in Xpath") 17 | // public void testParentXpath(){ 18 | // FrameworkPage mainPage = pages.get(String.valueOf(PagesType.MARKUP)); 19 | // 20 | // mainpage.openPage(); 21 | // .generateMarkup(); 22 | // 23 | // while (!mainPage.displayedText()) 24 | // mainPage.generateMarkup(); 25 | // 26 | // mainPage.selectFirstCheckbox(); 27 | // boolean result = mainPage.verifyFirstAccountCheckbox(); 28 | // assertTrue(result, "Verify first account checkbox checked"); 29 | // 30 | // mainPage.selectFirstAccountCheckbox(); 31 | // result = mainPage.verifyFirstAccountCheckbox(); //should be healed 32 | // assertTrue(result, "Verify first account checkbox unchecked"); 33 | // } 34 | 35 | // @Test 36 | // @Severity(SeverityLevel.MINOR) 37 | // @Description("Select and verify several inputs via parent.findElement") 38 | // public void testUnderParentFindElements() { 39 | // FrameworkPage mainPage = pages.get(String.valueOf(PagesType.MARKUP)); 40 | // 41 | // mainpage.openPage(); 42 | // .generateMarkup(); 43 | // 44 | // while (!mainPage.groupInputEnabled()) 45 | // mainPage.generateMarkup(); 46 | // 47 | // // find all locator and fill them. verify their values 48 | // mainPage.verifyInputText(); //no healing 49 | // mainPage.fillInputsGroup(); 50 | // mainPage.verifyInputText(); //should be healed 51 | // } 52 | 53 | @Test 54 | @Severity(SeverityLevel.NORMAL) 55 | @Description("Select and verify several inputs CSS FirstChild") 56 | public void testCSSFirstChild() { 57 | FrameworkPage page = pages.get(TEST_ENV); 58 | 59 | page.openPage(); 60 | driver.findElement(By.cssSelector("test_tag:first-child")); 61 | page.clickSubmitButton(); 62 | driver.findElement(By.cssSelector("test_tag:first-child")); 63 | } 64 | 65 | @Test 66 | @Severity(SeverityLevel.NORMAL) 67 | @Description("Select and verify several inputs CSS LastChild") 68 | public void testCSSLastChild() { 69 | FrameworkPage page = pages.get(TEST_ENV); 70 | 71 | page.openPage(); 72 | driver.findElement(By.cssSelector("child_tag:last-child")); 73 | page.clickSubmitButton(); 74 | driver.findElement(By.cssSelector("child_tag:last-child")); 75 | } 76 | 77 | // @Test 78 | // @Severity(SeverityLevel.NORMAL) 79 | // @Description("Select first checkbox and verify using parent.findElements in Xpath. " + 80 | // "The difference between first - not use @DisabledHealing") 81 | // public void testXPathUnderParentFindElements() { 82 | // FrameworkPage page = pages.get(String.valueOf(PagesType.TEST_ENV)); 83 | // 84 | // String parentXpath = "//*[contains(@class,'test-form')]"; 85 | // String childXpath = "//*[@class='input1']"; 86 | // page.openPage(); 87 | // .findElementsUnderParent(parentXpath, childXpath) 88 | // .clickFormButton() 89 | // .findElementsUnderParent(parentXpath, childXpath); 90 | // } 91 | // selenium 4 (above, below, toLeftOf, toRightOf, near) 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/com/epam/healenium/tests/SemanticTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.tests; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import io.qameta.allure.Description; 5 | import io.qameta.allure.Severity; 6 | import io.qameta.allure.SeverityLevel; 7 | import org.junit.jupiter.api.Test; 8 | import org.openqa.selenium.By; 9 | 10 | import static com.epam.healenium.constants.PagesType.TEST_ENV; 11 | 12 | public class SemanticTest extends BaseTest { 13 | 14 | @Test 15 | @Severity(SeverityLevel.NORMAL) 16 | @Description("Button click with find element by id") 17 | public void testButtonClickWithId() { 18 | FrameworkPage page = pages.get(TEST_ENV); 19 | 20 | page.openPage(); 21 | driver.findElement(By.id("change_id")); 22 | page.clickSubmitButton(); 23 | driver.findElement(By.id("change_id")); 24 | } 25 | 26 | // @Test 27 | // @Severity(SeverityLevel.NORMAL) 28 | // @Description("Find element by classname") 29 | // public void testFindElementByClassName() { 30 | // FrameworkPage mainPage = pages.get(String.valueOf(PagesType.MARKUP)); 31 | // 32 | // mainPage.openPage() 33 | // .clickTestButton(); 34 | // mainPage.confirmAlert(); 35 | // 36 | // mainPage 37 | // .generateMarkup() 38 | // .clickTestButton(); //should be healed 39 | // mainPage.confirmAlert(); 40 | // 41 | // } 42 | 43 | 44 | @Test 45 | @Severity(SeverityLevel.MINOR) 46 | @Description("Find element by linktext") 47 | public void testFindElementByLinkText() { 48 | FrameworkPage page = pages.get(TEST_ENV); 49 | 50 | page.openPage(); 51 | driver.findElement(By.linkText("Change: LinkText, PartialLinkText")); 52 | page.clickSubmitButton(); 53 | driver.findElement(By.linkText("Change: LinkText, PartialLinkText")); 54 | } 55 | 56 | @Test 57 | @Severity(SeverityLevel.NORMAL) 58 | @Description("Find element by name") 59 | public void testFindElementByName() { 60 | FrameworkPage page = pages.get(TEST_ENV); 61 | 62 | page.openPage(); 63 | driver.findElement(By.name("change_name")); 64 | page.clickSubmitButton(); 65 | driver.findElement(By.name("change_name")); 66 | } 67 | 68 | @Test 69 | @Severity(SeverityLevel.MINOR) 70 | @Description("Find element by partialLinkText") 71 | public void testFindElementByPartialLinkText() { 72 | FrameworkPage page = pages.get(TEST_ENV); 73 | 74 | page.openPage(); 75 | driver.findElement(By.partialLinkText("PartialLinkText")); 76 | page.clickSubmitButton(); 77 | driver.findElement(By.partialLinkText("PartialLinkText")); 78 | } 79 | 80 | @Test 81 | @Severity(SeverityLevel.MINOR) 82 | @Description("Find element by tagName") 83 | public void testFindElementByTagName() { 84 | FrameworkPage page = pages.get(TEST_ENV); 85 | 86 | page.openPage(); 87 | driver.findElement(By.tagName("test_tag")).isDisplayed(); 88 | page.clickSubmitButton(); 89 | driver.findElement(By.tagName("test_tag")).isDisplayed(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/test/java/com/epam/healenium/tests/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.tests; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import io.qameta.allure.Description; 5 | import io.qameta.allure.Severity; 6 | import io.qameta.allure.SeverityLevel; 7 | import org.junit.jupiter.api.Test; 8 | import org.openqa.selenium.By; 9 | 10 | import static com.epam.healenium.constants.PagesType.TEST_ENV; 11 | 12 | public class SimpleTest extends BaseTest { 13 | 14 | @Test 15 | @Severity(SeverityLevel.NORMAL) 16 | @Description("Update locator for element with css id") 17 | public void testCssId() { 18 | FrameworkPage page = pages.get(TEST_ENV); 19 | 20 | page.openPage(); 21 | page.clickSubmitButton(); 22 | driver.findElement(By.cssSelector("#change_id")); 23 | } 24 | 25 | @Test 26 | @Severity(SeverityLevel.NORMAL) 27 | @Description("Update locator for element with css Enabled") 28 | public void testCssEnabled() { 29 | FrameworkPage page = pages.get(TEST_ENV); 30 | 31 | page.openPage(); 32 | page.clickSubmitButton(); 33 | driver.findElement(By.cssSelector("textarea:enabled")); 34 | } 35 | 36 | @Test 37 | @Severity(SeverityLevel.NORMAL) 38 | @Description("XPath Not Contains") 39 | public void testXpathNotContains() { 40 | FrameworkPage page = pages.get(TEST_ENV); 41 | 42 | page.openPage(); 43 | page.clickSubmitButton(); 44 | driver.findElement(By.xpath("//input[not(contains(@class, 'input1'))]")); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/com/epam/healenium/tests/WaitTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.tests; 2 | 3 | import com.epam.healenium.SelfHealingDriver; 4 | import io.qameta.allure.Description; 5 | import io.qameta.allure.Severity; 6 | import io.qameta.allure.SeverityLevel; 7 | import org.junit.jupiter.api.Assertions; 8 | import org.junit.jupiter.api.Test; 9 | import org.openqa.selenium.By; 10 | import org.openqa.selenium.JavascriptExecutor; 11 | import org.openqa.selenium.WebElement; 12 | import org.openqa.selenium.support.ui.ExpectedConditions; 13 | import org.openqa.selenium.support.ui.WebDriverWait; 14 | 15 | import java.time.Duration; 16 | 17 | import static com.epam.healenium.constants.PagesType.TEST_ENV; 18 | 19 | public class WaitTest extends BaseTest { 20 | 21 | @Test 22 | @Severity(SeverityLevel.NORMAL) 23 | @Description("Disable healing for Proxy approach") 24 | public void testConditionWait() { 25 | pages.get(TEST_ENV).openPage(); 26 | if (!(driver instanceof SelfHealingDriver)) { 27 | driver.findElement(By.id("Wait_Submit")).click(); 28 | JavascriptExecutor js = (JavascriptExecutor) driver; 29 | js.executeScript("disable_healing_true"); 30 | WebElement element = new WebDriverWait(driver, Duration.ofSeconds(10)) 31 | .until(ExpectedConditions.visibilityOfElementLocated(By.id("wait_new_element"))); 32 | js.executeScript("disable_healing_false"); 33 | Assertions.assertEquals("Wait input", element.getAttribute("placeholder")); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/epam/healenium/tests/XpathTest.java: -------------------------------------------------------------------------------- 1 | package com.epam.healenium.tests; 2 | 3 | import com.epam.healenium.FrameworkPage; 4 | import io.qameta.allure.Description; 5 | import io.qameta.allure.Severity; 6 | import io.qameta.allure.SeverityLevel; 7 | import org.junit.jupiter.api.Test; 8 | import org.openqa.selenium.By; 9 | 10 | import static com.epam.healenium.constants.PagesType.TEST_ENV; 11 | 12 | public class XpathTest extends BaseTest { 13 | 14 | @Test 15 | @Severity(SeverityLevel.NORMAL) 16 | @Description("XPath with special characters") 17 | public void testXpathSpecialCharacter() { 18 | FrameworkPage page = pages.get(TEST_ENV); 19 | 20 | page.openPage(); 21 | driver.findElement(By.xpath("//*[@id='change:name']")); 22 | page.clickSubmitButton(); 23 | driver.findElement(By.xpath("//*[@id='change:name']")); 24 | } 25 | 26 | @Test 27 | @Severity(SeverityLevel.MINOR) 28 | @Description("XPath Following") 29 | public void testXpathFollowing() { 30 | FrameworkPage page = pages.get(TEST_ENV); 31 | 32 | page.openPage(); 33 | driver.findElement(By.xpath("//*[@id='change_className']/following::test_tag")); 34 | page.clickSubmitButton(); 35 | driver.findElement(By.xpath("//*[@id='change_className']/following::test_tag")); 36 | } 37 | 38 | @Test 39 | @Severity(SeverityLevel.NORMAL) 40 | @Description("XPath Contains") 41 | public void testXpathContains() { 42 | FrameworkPage page = pages.get(TEST_ENV); 43 | 44 | page.openPage(); 45 | driver.findElement(By.xpath("//input[contains(@class, 'test')]")); 46 | page.clickSubmitButton(); 47 | driver.findElement(By.xpath("//input[contains(@class, 'test')]")); 48 | } 49 | 50 | @Test 51 | @Severity(SeverityLevel.NORMAL) 52 | @Description("XPath Not Contains") 53 | public void testXpathNotContains() { 54 | FrameworkPage page = pages.get(TEST_ENV); 55 | 56 | page.openPage(); 57 | driver.findElement(By.xpath("//input[not(contains(@class, 'input1'))]")); 58 | page.clickSubmitButton(); 59 | driver.findElement(By.xpath("//input[not(contains(@class, 'input1'))]")); 60 | } 61 | 62 | @Test 63 | @Severity(SeverityLevel.MINOR) 64 | @Description("XPath Following-Sibling") 65 | public void testXpathFollowingSibling() { 66 | FrameworkPage page = pages.get(TEST_ENV); 67 | 68 | page.openPage(); 69 | driver.findElement(By.xpath("//*[starts-with(@class, 'test')]/following-sibling::*")); 70 | page.clickSubmitButton(); 71 | driver.findElement(By.xpath("//*[starts-with(@class, 'test')]/following-sibling::*")); 72 | } 73 | 74 | @Test 75 | @Severity(SeverityLevel.MINOR) 76 | @Description("XPath Ancestor::") 77 | public void testXPathAncestor() { 78 | FrameworkPage page = pages.get(TEST_ENV); 79 | 80 | page.openPage(); 81 | driver.findElement(By.xpath("(//*[starts-with(@class, 'test')]/ancestor::div[@class='healenium-form validate-form']//input)[1]")); 82 | page.clickSubmitButton(); 83 | driver.findElement(By.xpath("(//*[starts-with(@class, 'test')]/ancestor::div[@class='healenium-form validate-form']//input)[1]")); 84 | } 85 | 86 | @Test 87 | @Severity(SeverityLevel.MINOR) 88 | @Description("XPath OR") 89 | public void testXpathOR() { 90 | FrameworkPage page = pages.get(TEST_ENV); 91 | 92 | page.openPage(); 93 | driver.findElement(By.xpath("//*[@id='change_id' or @id='omg']")); 94 | page.clickSubmitButton(); 95 | driver.findElement(By.xpath("//*[@id='change_id' or @id='omg']")); 96 | } 97 | 98 | @Test 99 | @Severity(SeverityLevel.MINOR) 100 | @Description("XPath And") 101 | public void testXpathAnd() { 102 | FrameworkPage page = pages.get(TEST_ENV); 103 | 104 | page.openPage(); 105 | driver.findElement(By.xpath("//*[@id='change_id' and @type='text']")); 106 | page.clickSubmitButton(); 107 | driver.findElement(By.xpath("//*[@id='change_id' and @type='text']")); 108 | } 109 | 110 | @Test 111 | @Severity(SeverityLevel.NORMAL) 112 | @Description("XPath Starts-with") 113 | public void testXpathStartsWith() { 114 | FrameworkPage page = pages.get(TEST_ENV); 115 | 116 | page.openPage(); 117 | driver.findElement(By.xpath("//*[starts-with(@class, 'test')]")); 118 | page.clickSubmitButton(); 119 | driver.findElement(By.xpath("//*[starts-with(@class, 'test')]")); 120 | } 121 | 122 | @Test 123 | @Severity(SeverityLevel.MINOR) 124 | @Description("XPath Precending::") 125 | public void testXpathPrecending() { 126 | FrameworkPage page = pages.get(TEST_ENV); 127 | 128 | page.openPage(); 129 | driver.findElement(By.xpath("//*[@id='change_className']/preceding::*[@id='change_id']")); 130 | page.clickSubmitButton(); 131 | driver.findElement(By.xpath("//*[@id='change_className']/preceding::*[@id='change_id']")); 132 | } 133 | 134 | @Test 135 | @Severity(SeverityLevel.MINOR) 136 | @Description("XPath Descendant::") 137 | public void testXpathDescendant() { 138 | FrameworkPage page = pages.get(TEST_ENV); 139 | 140 | page.openPage(); 141 | driver.findElement(By.xpath("//*[@id='descendant_change']/descendant::input")); 142 | page.clickSubmitButton(); 143 | driver.findElement(By.xpath("//*[@id='descendant_change']/descendant::input")); 144 | } 145 | 146 | @Test 147 | @Severity(SeverityLevel.MINOR) 148 | @Description("XPath Hover") 149 | public void testXpathHover() { 150 | 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/test/resources/healenium.properties: -------------------------------------------------------------------------------- 1 | recovery-tries = 1 2 | score-cap = .6 3 | heal-enabled = true 4 | hlm.server.url = http://localhost:7878 5 | hlm.imitator.url = http://localhost:8000 -------------------------------------------------------------------------------- /src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.execution.parallel.enabled = false 2 | junit.jupiter.execution.parallel.mode.default = concurrent 3 | junit.jupiter.execution.parallel.mode.classes.default = concurrent -------------------------------------------------------------------------------- /src/test/resources/properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "frameworks": [ 3 | { 4 | "framework": "selenium" 5 | } 6 | ], 7 | "capabilities": [ 8 | { 9 | "browserName": "chrome", 10 | "version": "96", 11 | "goog:chromeOptions": { 12 | "args": [ 13 | "--no-sandbox", 14 | "--disable-dev-shm-usage" 15 | ] 16 | } 17 | }, 18 | { 19 | "browser": "chrome", 20 | "version": "95", 21 | "goog:chromeOptions": { 22 | "args": [ 23 | "--no-sandbox", 24 | "--disable-dev-shm-usage" 25 | ] 26 | } 27 | }, 28 | { 29 | "browser": "firefox", 30 | "version": "89" 31 | }, 32 | { 33 | "browser": "MicrosoftEdge", 34 | "platform": "LINUX", 35 | "edgeOptions": { 36 | "args": [ 37 | "--no-sandbox", 38 | "--disable-dev-shm-usage" 39 | ] 40 | } 41 | } 42 | ] 43 | } --------------------------------------------------------------------------------