├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── ReadMeImages ├── FailureReport.PNG ├── OverallReport.PNG └── PDFReport.PNG ├── pom.xml └── src ├── main └── java │ ├── factory │ └── DriverFactory.java │ ├── pages │ ├── AlertsFramesWindowsPage.java │ ├── ElementsPage.java │ ├── InteractionsPage.java │ ├── LoginPage.java │ └── WidgetsPage.java │ └── utils │ ├── ConfigReader.java │ ├── WebActions.java │ └── functional │ ├── Students.xlsx │ └── sampleFile.jpeg └── test ├── java ├── hooks │ └── Hooks.java ├── stepdefinitions │ ├── AlertsFramesWindowsSteps.java │ ├── ElementsSteps.java │ ├── InteractionsSteps.java │ ├── LoginSteps.java │ └── WidgetsSteps.java └── testrunner │ ├── ReRunner.java │ └── TestRunner.java └── resources ├── config └── config.properties ├── extent-config.xml ├── extent.properties └── features ├── AlertsFrameWindows.feature ├── Elements.feature ├── ExcelReader.feature ├── Interactions.feature ├── Login.feature └── Widgets.feature /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Downloads/ 3 | .idea/ 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Thank you for investing your time in contributing to my project! 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. 4 | 5 | Please note we have a code of conduct, please follow it in all your interactions with the project. 6 | 7 | See the README to get an overview of the project. 8 | 9 | !!! HAPPY TESTING !!! -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 akshayp7 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 | Table of Contents 5 |
6 |
    7 |
  1. 8 | About the Project 9 | 12 |
  2. 13 |
  3. 14 | Getting Started 15 | 19 |
  4. 20 |
  5. Usage
  6. 21 |
  7. Reports
  8. 22 |
23 |
24 |
25 |

26 | 27 | 28 | 29 | ## About the Project 30 | 31 | Playwright Demo - This project is based on Microsoft Playwright which enables reliable end-to-end testing for modern web 32 | apps. 33 | 34 | Top Features: 35 | 36 | - Easy to Configure. 37 | - Auto-waits for all the relevant checks to pass and only then performs the requested action. 38 | - Records the test script and every action on the target page is turned into generated script. 39 | - Generates trace file on failure, which gives in-depth details of Test Case execution. 40 | - Execution of test case is faster when compared with other competitive framework in market. 41 | - Supports Headful/Headless mode execution for Firefox/Webkit/Google Chrome/Chromium/MS Edge on Windows/Linux/Mac 42 | machines. 43 | - Rerun Failed Test cases 44 | - Supports 'download' event monitoring, so there is no need for user to actually wait for downloads to finish. 45 | - Supports Serial and Parallel execution. 46 | - Spark PDF/HTML Reports are generated after execution with an option to capture screenshot/video/trace file on failure. 47 | - Nonetheless Support from Microsoft so FREQUENT RELEASES and turn around time for any queries is 48 hours. 48 | 49 | ### Built With 50 | 51 | - [Playwright](https://playwright.dev) 52 | - [Cucumber](https://cucumber.io/) 53 | - [JUnit](https://junit.org/junit5/) 54 | - [Maven](https://maven.apache.org/) 55 | - [OpenJDK](https://www.openlogic.com/openjdk-downloads) 56 | 57 | ## Getting Started 58 | 59 | ### Prerequisites 60 | 61 | The following software are required: 62 | 63 | - java : Download and Install java 1.8 64 | ```sh 65 | https://www.openlogic.com/openjdk-downloads 66 | ``` 67 | - Maven must be configured 68 | 69 | ### Installation 70 | 71 | 1. Clone the repo using below URL 72 | 73 | ```sh 74 | https://github.com/akshayp7/playwright-typescipt-playwright-test.git 75 | ``` 76 | 77 | 2. Navigate to folder and install dependencies using: 78 | 79 | ```sh 80 | mvn clean install 81 | ``` 82 | 83 | 84 | 85 | ## Usage 86 | 87 | 1. For Browser Configuration, change required value in browser and headless mode in `src/test/resources/config/config.properties`. 88 | 2. For executing test cases in parallel, navigate to pom.xml and in plugin in configuration section 89 | provide `false` 90 | Now if you want to run 4 features in parallel provide `4` in maven-failsafe-plugin section 91 | in pom.xml and execute below command 92 | ```JS 93 | mvn verify 94 | ``` 95 | 3. For executing test cases in sequence, provide a suitable tag `@smoke` at the start of your scenario and execute below 96 | command: 97 | ```JS 98 | mvn test "-Dcucumber. options=--tags @smoke" 99 | ``` 100 | 4. For recording test scripts execute below command with desired url: 101 | ```JS 102 | mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="codegen https://demoqa.com/" 103 | ``` 104 | 5. For HTML Report configuration navigate to `src/test/resources/extent.properties` and provide destination folder as 105 | value in `extent.reporter.spark.out` 106 | 6. For PDF Report configuration navigate to `src/test/resources/extent.properties` and provide destination folder as 107 | value in `extent.reporter.pdf.out` 108 | 7. Screenshots and Trace files will be generated in target folder on failure this configuration is provided 109 | in `src/test/java/hooks/Hooks.java` in `takeScreenshotAndTrace` method. 110 | 8. To change your username go to `src/test/resources/config/config.properties` and provide value against `adminUsername` 111 | 9. To change password, go to `src/main/java/utils/WebActions.java` in `encrypt()` and 112 | replace `yourPassword` with your password, execute the test case, Encrypted password will be printed on your 113 | console . 114 | Copy Encrypted password in `src/test/resources/config/config.properties` against `adminPassword` field. 115 | 10. You can even execute test cases by running `src/test/java/testrunner/TestRunner.java` file all the failed test cases 116 | are saved in `target/rerun.txt` 117 | 11. For rerunning failed test cases run `src/test/java/testrunner/ReRunner.java` 118 | 12. Reports will be generated in `target/HTMLReport` and `target/PdfReport` folders. 119 | 120 | ## Reports 121 | 122 | - Overall Report 123 | ![Overall Report Screenshot][overall-report-screenshot] 124 | 125 | - Failure Report 126 | ![Failure Report Screenshot][failure-report-screenshot] 127 | 128 | - PDF Report 129 | ![PDF Report Screenshot][pdf-report-screenshot] 130 | 131 | 132 | 133 | [overall-report-screenshot]: ReadMeImages/OverallReport.PNG 134 | 135 | [failure-report-screenshot]: ReadMeImages/FailureReport.PNG 136 | 137 | [pdf-report-screenshot]: ReadMeImages/PDFReport.PNG -------------------------------------------------------------------------------- /ReadMeImages/FailureReport.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshayp7/playwright-java-cucumber/f722d271eb159e1845a3c61627d667bcb1a9c292/ReadMeImages/FailureReport.PNG -------------------------------------------------------------------------------- /ReadMeImages/OverallReport.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshayp7/playwright-java-cucumber/f722d271eb159e1845a3c61627d667bcb1a9c292/ReadMeImages/OverallReport.PNG -------------------------------------------------------------------------------- /ReadMeImages/PDFReport.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshayp7/playwright-java-cucumber/f722d271eb159e1845a3c61627d667bcb1a9c292/ReadMeImages/PDFReport.PNG -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | playwright-java-cucumber 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 8 13 | 8 14 | 1.8 15 | UTF-8 16 | 4.13.2 17 | 7.11.1 18 | 3.8.1 19 | 2.22.2 20 | 21 | 22 | 23 | 24 | io.cucumber 25 | cucumber-java 26 | ${cucumber.version} 27 | test 28 | 29 | 30 | 31 | io.cucumber 32 | cucumber-junit 33 | ${cucumber.version} 34 | test 35 | 36 | 37 | 38 | junit 39 | junit 40 | ${junit.version} 41 | test 42 | 43 | 44 | 45 | 46 | com.microsoft.playwright 47 | playwright 48 | 1.31.0 49 | 50 | 51 | 52 | 53 | tech.grasshopper 54 | extentreports-cucumber7-adapter 55 | 1.10.1 56 | 57 | 58 | 59 | org.projectlombok 60 | lombok 61 | 1.18.22 62 | 63 | 64 | 65 | 66 | org.apache.poi 67 | poi 68 | 5.2.3 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | org.apache.maven.plugins 77 | maven-compiler-plugin 78 | ${maven.compiler.version} 79 | 80 | UTF-8 81 | ${java.version} 82 | ${java.version} 83 | 84 | 85 | 86 | org.apache.maven.plugins 87 | maven-surefire-plugin 88 | ${maven.surefire.version} 89 | 90 | false 91 | 92 | 93 | 94 | 95 | org.apache.maven.plugins 96 | maven-failsafe-plugin 97 | 3.0.0-M9 98 | 99 | 100 | 101 | integration-test 102 | 103 | 104 | 105 | **/TestRunner.java 106 | 107 | methods 108 | 4 109 | true 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/main/java/factory/DriverFactory.java: -------------------------------------------------------------------------------- 1 | package factory; 2 | 3 | import com.microsoft.playwright.*; 4 | import utils.WebActions; 5 | 6 | public class DriverFactory { 7 | public Browser browser; 8 | public static BrowserContext context; 9 | public static Page page; 10 | 11 | public static ThreadLocal threadLocalDriver = new ThreadLocal<>(); //For Parallel execution 12 | public static ThreadLocal threadLocalContext = new ThreadLocal<>(); 13 | 14 | //Launches Browser as set by user in config file 15 | public Page initDriver(String browserName) { 16 | BrowserType browserType = null; 17 | boolean headless = Boolean.valueOf(WebActions.getProperty("headless")); 18 | switch (browserName) { 19 | case "firefox": 20 | browserType = Playwright.create().firefox(); 21 | browser = browserType.launch(new BrowserType.LaunchOptions().setHeadless(headless)); 22 | break; 23 | case "chrome": 24 | browserType = Playwright.create().chromium(); 25 | browser = browserType.launch(new BrowserType.LaunchOptions().setChannel("chrome").setHeadless(headless)); 26 | break; 27 | case "webkit": 28 | browserType = Playwright.create().webkit(); 29 | browser = browserType.launch(new BrowserType.LaunchOptions().setHeadless(headless)); 30 | break; 31 | } 32 | if (browserType == null) throw new IllegalArgumentException("Could not Launch Browser for type" + browserType); 33 | context = browser.newContext(); 34 | //Below line is used to start the trace file 35 | context.tracing().start(new Tracing.StartOptions().setScreenshots(true).setSnapshots(true).setSources(false)); 36 | page = context.newPage(); 37 | threadLocalDriver.set(page); 38 | threadLocalContext.set(context); 39 | return page; 40 | } 41 | 42 | public static synchronized Page getPage() { 43 | return threadLocalDriver.get(); // Will return Initialized Thread Local Driver 44 | } 45 | 46 | public static synchronized BrowserContext getContext() { 47 | return threadLocalContext.get(); // Will return Initialized Thread Local Context 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/pages/AlertsFramesWindowsPage.java: -------------------------------------------------------------------------------- 1 | package pages; 2 | 3 | import com.microsoft.playwright.BrowserContext; 4 | import com.microsoft.playwright.Locator; 5 | import com.microsoft.playwright.Page; 6 | 7 | public class AlertsFramesWindowsPage { 8 | private Page page; 9 | private BrowserContext context; 10 | private final Locator NEW_TAB_BUTTON; 11 | private final Locator NEW_WINDOW_BUTTON; 12 | private final Locator PROMPT_ALERT_BUTTON; 13 | private final Locator PROMPT_RESULT; 14 | private final Locator FRAME_LOCATOR; 15 | private final Locator NESTED_CHILDFRAME_LOCATOR; 16 | 17 | public AlertsFramesWindowsPage(Page page, BrowserContext context) { 18 | this.page = page; 19 | this.context = context; 20 | this.NEW_TAB_BUTTON = page.getByText("New Tab"); 21 | this.NEW_WINDOW_BUTTON = page.getByText("New Window", new Page.GetByTextOptions().setExact(true)); 22 | this.PROMPT_ALERT_BUTTON = page.locator("#promtButton"); 23 | this.PROMPT_RESULT = page.locator("#promptResult"); 24 | this.FRAME_LOCATOR = page.frameLocator("#frame2").locator("#sampleHeading"); 25 | //Nested Iframe Locator 26 | this.NESTED_CHILDFRAME_LOCATOR = page.frameLocator("#frame1").frameLocator("iframe").getByText("Child Iframe"); 27 | } 28 | 29 | 30 | public void clickAlertFrameWinNavBar(String navbarOption) { 31 | this.page.getByText(navbarOption, new Page.GetByTextOptions().setExact(true)).click(); 32 | } 33 | 34 | public boolean verifyNewTabURL(String newTabURL) { 35 | // Get page after a specific action (e.g. clicking a link) 36 | Page newPage = this.context.waitForPage(() -> { 37 | this.NEW_TAB_BUTTON.click(); // Opens a new tab 38 | }); 39 | newPage.waitForLoadState(); 40 | String newPageURL = newPage.url(); 41 | newPage.close(); 42 | return (newPageURL.equals(newTabURL)); 43 | } 44 | 45 | public boolean verifyNewWinURL(String newWinURL) { 46 | // Get page after a specific action (e.g. clicking a link) 47 | Page newPage = this.context.waitForPage(() -> { 48 | this.NEW_WINDOW_BUTTON.click(); // Opens a new tab 49 | }); 50 | newPage.waitForLoadState(); 51 | String newPageURL = newPage.url(); 52 | newPage.close(); 53 | return (newPageURL.equals(newWinURL)); 54 | } 55 | 56 | public void enterTextAndAcceptAlert(String alertText) { 57 | this.page.onDialog(dialog -> dialog.accept(alertText)); 58 | this.PROMPT_ALERT_BUTTON.click(); 59 | } 60 | 61 | public boolean verifyAlertText(String alertText) { 62 | return this.PROMPT_RESULT.textContent().contains(alertText); 63 | } 64 | 65 | public boolean verifyFrameText(String frameText) { 66 | return this.FRAME_LOCATOR.textContent().contains(frameText); 67 | } 68 | 69 | public boolean verifyNestedFrameChildText() { 70 | return this.NESTED_CHILDFRAME_LOCATOR.isVisible(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/pages/ElementsPage.java: -------------------------------------------------------------------------------- 1 | package pages; 2 | 3 | import com.microsoft.playwright.Download; 4 | import com.microsoft.playwright.Locator; 5 | import com.microsoft.playwright.Page; 6 | import com.microsoft.playwright.options.AriaRole; 7 | import com.microsoft.playwright.options.MouseButton; 8 | 9 | import java.nio.file.Path; 10 | import java.nio.file.Paths; 11 | 12 | public class ElementsPage { 13 | private Page page; 14 | private final Locator FULL_NAME_EDITBOX; 15 | private final Locator SUBMIT_BUTTON; 16 | private final Locator SUBMITTED_TEXT; 17 | private final Locator HOME_CHECK_BOX; 18 | private final Locator HOME_SELECTED_TEXT; 19 | private final Locator NO_RADIO_BUTTON; 20 | private final Locator WEB_TABLES_HEADER; 21 | private final Locator WEB_TABLES_EDIT_ICON; 22 | private final Locator REGISTRATION_FORM_HEADER; 23 | private final Locator REGISTRATION_FORM_CLOSE_BUTTON; 24 | private final Locator DOUBLE_CLICK_BUTTON; 25 | private final Locator DOUBLE_CLICK_TEXT; 26 | private final Locator RIGHT_CLICK_BUTTON; 27 | private final Locator RIGHT_CLICK_TEXT; 28 | private final Locator HOME_LINK; 29 | private final Locator DOWNLOAD_BUTTON; 30 | private final Locator UPLOAD_BUTTON; 31 | private final Locator UPLOADED_FILE_TEXT; 32 | 33 | public ElementsPage(Page page) { 34 | this.page = page; 35 | this.FULL_NAME_EDITBOX = page.getByPlaceholder("Full Name"); 36 | this.SUBMIT_BUTTON = page.getByText("Submit"); 37 | this.SUBMITTED_TEXT = page.getByText("Name:AutoTest", new Page.GetByTextOptions().setExact(true)); // Matches exact text 38 | this.HOME_CHECK_BOX = page.getByText("Home"); 39 | this.HOME_SELECTED_TEXT = page.locator(".display-result"); 40 | this.NO_RADIO_BUTTON = page.locator("#noRadio"); // Using CSS Selector 41 | this.WEB_TABLES_HEADER = page.getByRole(AriaRole.COLUMNHEADER); 42 | this.WEB_TABLES_EDIT_ICON = page.getByRole(AriaRole.ROW, new Page.GetByRoleOptions().setName("Cierra")).getByTitle("Edit").locator("svg"); // Chaining Locators 43 | this.REGISTRATION_FORM_HEADER = page.getByText("Registration Form"); 44 | this.REGISTRATION_FORM_CLOSE_BUTTON = page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Close")); 45 | this.DOUBLE_CLICK_BUTTON = page.locator("#doubleClickBtn"); 46 | this.DOUBLE_CLICK_TEXT = page.getByText("You have done a double click"); 47 | this.RIGHT_CLICK_BUTTON = page.locator("#rightClickBtn"); 48 | this.RIGHT_CLICK_TEXT = page.getByText("You have done a right click"); 49 | this.HOME_LINK = page.getByText("Home", new Page.GetByTextOptions().setExact(true)); 50 | this.DOWNLOAD_BUTTON = page.locator("#downloadButton"); 51 | this.UPLOAD_BUTTON = page.locator("#uploadFile"); 52 | this.UPLOADED_FILE_TEXT = page.getByText("sampleFile.jpeg"); 53 | } 54 | 55 | public void clickElementNavBar(String navbarOption) { 56 | this.page.getByText(navbarOption, new Page.GetByTextOptions().setExact(true)).click(); 57 | } 58 | 59 | public void enterFullName(String fullName) { 60 | this.FULL_NAME_EDITBOX.fill(fullName); 61 | } 62 | 63 | public void clickSubmit() { 64 | this.SUBMIT_BUTTON.click(); 65 | } 66 | 67 | public boolean verifySubmittedText() { 68 | return this.SUBMITTED_TEXT.isVisible(); 69 | } 70 | 71 | public void clickHomeCheckBox() { 72 | this.HOME_CHECK_BOX.click(); 73 | } 74 | 75 | public boolean verifyCheckboxSelectedText(String checkBoxText) { 76 | return this.HOME_SELECTED_TEXT.textContent().contains(checkBoxText); 77 | } 78 | 79 | public boolean verifyNoRadioButtonDisabled() { 80 | return this.NO_RADIO_BUTTON.isDisabled(); 81 | } 82 | 83 | public boolean verifyFirstColumnTableHeader(String headerName) { 84 | String[] headerTexts = this.WEB_TABLES_HEADER.allTextContents().toArray(new String[0]); 85 | return headerTexts[0].equals(headerName); 86 | } 87 | 88 | public void editCierraEntry() { 89 | this.WEB_TABLES_EDIT_ICON.click(); 90 | } 91 | 92 | public boolean verifyRegistrationForm() { 93 | return this.REGISTRATION_FORM_HEADER.isVisible(); 94 | } 95 | 96 | public void registrationFormClose() { 97 | this.REGISTRATION_FORM_CLOSE_BUTTON.click(); 98 | } 99 | 100 | public void performClick(String clickType) { 101 | switch (clickType.toLowerCase()) { 102 | case "double": 103 | this.DOUBLE_CLICK_BUTTON.dblclick(); 104 | break; 105 | case "right": 106 | this.RIGHT_CLICK_BUTTON.click(new Locator.ClickOptions().setButton(MouseButton.RIGHT)); 107 | break; 108 | } 109 | } 110 | 111 | public boolean verifyClickSuccessMsg(String clickType) { 112 | boolean status = false; 113 | switch (clickType.toLowerCase()) { 114 | case "double": 115 | status = this.DOUBLE_CLICK_TEXT.isVisible(); 116 | break; 117 | case "right": 118 | status = this.RIGHT_CLICK_TEXT.isVisible(); 119 | break; 120 | } 121 | return status; 122 | } 123 | 124 | public void verifyFileDownload() { 125 | //Path for Downloads folder from root of project 126 | String downloadsDirectory = System.getProperty("user.dir") + "/Downloads/"; 127 | // Wait for the download to start and perform the action that initiates download Lambda expression 128 | Download download = page.waitForDownload(this.DOWNLOAD_BUTTON::click); 129 | // Wait for the download process to complete 130 | Path path = download.path(); 131 | // Save downloaded file in Downloads directory 132 | download.saveAs(Paths.get(downloadsDirectory + download.suggestedFilename())); 133 | } 134 | 135 | public void performFileUpload(String fileName) { 136 | String uploadFilePath = System.getProperty("user.dir") + "/src/main/java/utils/functional/" + fileName; 137 | this.UPLOAD_BUTTON.setInputFiles(Paths.get(uploadFilePath)); 138 | } 139 | 140 | public boolean verifyFileUpload(String fileName) { 141 | return this.page.getByText(fileName).isVisible(); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/pages/InteractionsPage.java: -------------------------------------------------------------------------------- 1 | package pages; 2 | 3 | import com.microsoft.playwright.Locator; 4 | import com.microsoft.playwright.Page; 5 | import com.microsoft.playwright.options.AriaRole; 6 | 7 | public class InteractionsPage { 8 | private Page page; 9 | private final Locator DRAGGABLE; 10 | private final Locator DROPPABLE; 11 | 12 | public InteractionsPage(Page page) { 13 | this.page = page; 14 | this.DRAGGABLE = page.getByRole(AriaRole.TABPANEL, new Page.GetByRoleOptions().setName("Simple")).locator("#draggable"); 15 | this.DROPPABLE = page.getByRole(AriaRole.TABPANEL, new Page.GetByRoleOptions().setName("Simple")).locator("#droppable"); 16 | } 17 | 18 | public void clickInteractionsNavBar(String navbarOption) { 19 | this.page.getByText(navbarOption, new Page.GetByTextOptions().setExact(true)).click(); 20 | } 21 | 22 | public void performDragAndDrop() { 23 | this.DRAGGABLE.hover(); 24 | this.page.mouse().down(); 25 | this.DROPPABLE.hover(); 26 | this.page.mouse().up(); 27 | } 28 | 29 | public boolean verifyDragAndDrop(String dropText) { 30 | return this.DROPPABLE.textContent().contains(dropText); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/pages/LoginPage.java: -------------------------------------------------------------------------------- 1 | package pages; 2 | 3 | import com.microsoft.playwright.Locator; 4 | import com.microsoft.playwright.Page; 5 | import utils.WebActions; 6 | 7 | public class LoginPage { 8 | private Page page; 9 | private final Locator USERNAME_EDITBOX; 10 | private final Locator PASSWORD_EDITBOX; 11 | private final Locator LOGIN_BUTTON; 12 | private final Locator BOOKS_SEARCH_BOX; 13 | 14 | public LoginPage(Page page) { 15 | this.page = page; 16 | this.USERNAME_EDITBOX = page.locator("#userName"); 17 | this.PASSWORD_EDITBOX = page.locator("#password"); 18 | this.LOGIN_BUTTON = page.locator("#login"); 19 | this.BOOKS_SEARCH_BOX = page.getByPlaceholder("Type to search"); 20 | } 21 | 22 | public void navigateToUrl(String url) { 23 | this.page.navigate(WebActions.getProperty(url)); 24 | } 25 | 26 | public void enterUsername(String username) { 27 | USERNAME_EDITBOX.fill(WebActions.getProperty(username)); 28 | } 29 | 30 | public void enterPassword(String password) { 31 | PASSWORD_EDITBOX.fill(WebActions.decrypt(password)); 32 | } 33 | 34 | public void clickLogin() { 35 | LOGIN_BUTTON.click(); 36 | } 37 | 38 | public void clickOnIcon(String iconName) { 39 | this.page.getByText(iconName, new Page.GetByTextOptions().setExact(true)).click(); // Clicks on the Exact text 40 | } 41 | 42 | public boolean verifyProfilePage() { 43 | return WebActions.waitUntilElementDisplayed(this.BOOKS_SEARCH_BOX, 60); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/pages/WidgetsPage.java: -------------------------------------------------------------------------------- 1 | package pages; 2 | 3 | import com.microsoft.playwright.Locator; 4 | import com.microsoft.playwright.Page; 5 | import com.microsoft.playwright.options.AriaRole; 6 | 7 | public class WidgetsPage { 8 | private Page page; 9 | private final Locator AUTOCOMPLETE_EDITBOX; 10 | private final Locator BLUE_COLOUR_TEXT; 11 | private final Locator HOVER_BUTTON; 12 | private final Locator TOOL_TIP_TEXT; 13 | private final Locator OLD_SELECT_MENU; 14 | private final Locator MULTISELECT_MENU; 15 | 16 | public WidgetsPage(Page page) { 17 | this.page = page; 18 | this.AUTOCOMPLETE_EDITBOX = page.locator("#autoCompleteSingleInput"); 19 | this.BLUE_COLOUR_TEXT = page.getByText("Blue", new Page.GetByTextOptions().setExact(true)); 20 | ; //Used to select Blue colour from Autocomplete editbox 21 | this.HOVER_BUTTON = page.locator("#toolTipButton"); 22 | this.TOOL_TIP_TEXT = page.getByRole(AriaRole.TOOLTIP); 23 | this.OLD_SELECT_MENU = page.locator("#oldSelectMenu"); 24 | this.MULTISELECT_MENU = page.getByText("Select..."); 25 | } 26 | 27 | public void clickWidgetsNavBar(String navbarOption) { 28 | this.page.getByText(navbarOption, new Page.GetByTextOptions().setExact(true)).click(); 29 | } 30 | 31 | public void fillAutocompleteTextField(String textValue) { 32 | this.AUTOCOMPLETE_EDITBOX.fill(textValue); 33 | this.BLUE_COLOUR_TEXT.click(); 34 | } 35 | 36 | public boolean verifyBlueColourSelected() { 37 | return this.BLUE_COLOUR_TEXT.isVisible(); 38 | } 39 | 40 | public void hoverOverButton() { 41 | this.HOVER_BUTTON.hover(); //Hover over element 42 | } 43 | 44 | public boolean verifyTooltip(String toolTip) { 45 | return this.TOOL_TIP_TEXT.textContent().equals(toolTip); 46 | } 47 | 48 | public void oldStyleSelectColour(String colorName) { 49 | this.OLD_SELECT_MENU.selectOption(colorName); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/utils/ConfigReader.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.io.FileInputStream; 4 | import java.util.Properties; 5 | 6 | public class ConfigReader { 7 | private Properties properties; 8 | 9 | //This is used to raed from properties files and returns properties object 10 | public Properties initProp() { 11 | properties = new Properties(); 12 | try { 13 | FileInputStream fileInputStream = new FileInputStream("./src/test/resources/config/config.properties"); 14 | properties.load(fileInputStream); 15 | } catch (Exception e) { 16 | System.out.println("Unable to read Properties file."); 17 | } 18 | return properties; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/utils/WebActions.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import com.microsoft.playwright.Locator; 4 | import org.apache.poi.ss.usermodel.Sheet; 5 | import org.apache.poi.ss.usermodel.Workbook; 6 | import org.apache.poi.ss.usermodel.WorkbookFactory; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.util.Base64; 11 | import java.util.Properties; 12 | 13 | public abstract class WebActions { 14 | 15 | public static String getProperty(String key) { 16 | ConfigReader configReader = new ConfigReader(); 17 | Properties properties = configReader.initProp(); // Reading from config properties file 18 | return properties.getProperty(key); 19 | } 20 | 21 | public static boolean waitUntilElementDisplayed(Locator locator, int timeoutSec) { 22 | boolean elementVisible = locator.isVisible(); 23 | int timer = 0; 24 | while (!elementVisible && timer < timeoutSec) { 25 | try { 26 | Thread.sleep(1000); 27 | elementVisible = locator.isVisible(); 28 | timer++; 29 | 30 | } catch (Exception e) { 31 | System.out.println(locator + "was not visible."); 32 | } 33 | } 34 | return elementVisible; 35 | } 36 | 37 | //base64 encoding: This is used to encrypt the password and save the encrypted value in config.properties file 38 | public static void encrypt() { 39 | try { 40 | byte[] encodedBytes = Base64.getEncoder().encode("yourPassword".getBytes("UTF-8")); 41 | String encodedValue = new String(encodedBytes); 42 | } catch (Exception e) { 43 | System.out.println("Password was not Encrypted."); 44 | } 45 | } 46 | 47 | //base64 decoding: This is used to decrypt the password from the encrypted value in config.properties file while passing to app 48 | public static String decrypt(String passwordField) { 49 | String encodedBytes = WebActions.getProperty(passwordField); 50 | String decodedString = ""; 51 | try { 52 | byte[] decodedBytes = Base64.getDecoder().decode(encodedBytes); 53 | decodedString = new String(decodedBytes); 54 | } catch (Exception e) { 55 | System.out.println("Password was nor Decrypted."); 56 | } 57 | return decodedString; 58 | } 59 | 60 | public static String getRowColValue(String filePath, String sheetName, int rowNum, int colNum) { 61 | String fileName = System.getProperty("user.dir") + "\\src\\main\\java\\utils\\functional\\" + filePath + ".xlsx"; 62 | Workbook workbook = null; 63 | try { 64 | workbook = WorkbookFactory.create(new File(fileName)); 65 | } catch (IOException e) { 66 | throw new RuntimeException(e); 67 | } 68 | Sheet sheet = workbook.getSheet(sheetName); 69 | return sheet.getRow(rowNum).getCell(colNum).getStringCellValue(); 70 | } 71 | } -------------------------------------------------------------------------------- /src/main/java/utils/functional/Students.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshayp7/playwright-java-cucumber/f722d271eb159e1845a3c61627d667bcb1a9c292/src/main/java/utils/functional/Students.xlsx -------------------------------------------------------------------------------- /src/main/java/utils/functional/sampleFile.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshayp7/playwright-java-cucumber/f722d271eb159e1845a3c61627d667bcb1a9c292/src/main/java/utils/functional/sampleFile.jpeg -------------------------------------------------------------------------------- /src/test/java/hooks/Hooks.java: -------------------------------------------------------------------------------- 1 | package hooks; 2 | 3 | import com.microsoft.playwright.Page; 4 | import com.microsoft.playwright.Tracing; 5 | import factory.DriverFactory; 6 | import io.cucumber.java.After; 7 | import io.cucumber.java.Before; 8 | import io.cucumber.java.Scenario; 9 | import utils.WebActions; 10 | 11 | import java.nio.file.Paths; 12 | 13 | public class Hooks { 14 | public DriverFactory driverFactory; 15 | public Page page; 16 | 17 | @Before 18 | public void launchBrowser() { 19 | String browserName = WebActions.getProperty("browser"); //Fetching browser value from config file 20 | driverFactory = new DriverFactory(); 21 | page = driverFactory.initDriver(browserName); // Passing browser name to launch the browser 22 | } 23 | 24 | //After runs in reverse order so order=1 will run first 25 | @After(order = 0) 26 | public void quitBrowser() { 27 | page.close(); 28 | } 29 | 30 | @After(order = 1) 31 | public void takeScreenshotAndTrace(Scenario scenario) { 32 | if (scenario.isFailed()) { 33 | String screenshotName = scenario.getName().replaceAll("", "_"); //Replace all space in scenario name with underscore 34 | byte[] sourcePath = page.screenshot(); 35 | scenario.attach(sourcePath, "image/png", screenshotName); //Attach screenshot to report if scenario fails 36 | DriverFactory.context.tracing().stop(new Tracing.StopOptions().setPath(Paths.get("target/" + screenshotName + ".zip"))); 37 | } 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/stepdefinitions/AlertsFramesWindowsSteps.java: -------------------------------------------------------------------------------- 1 | package stepdefinitions; 2 | 3 | import factory.DriverFactory; 4 | import io.cucumber.java.en.Then; 5 | import io.cucumber.java.en.When; 6 | import org.junit.Assert; 7 | import pages.AlertsFramesWindowsPage; 8 | 9 | public class AlertsFramesWindowsSteps { 10 | AlertsFramesWindowsPage alertsFramesWindowsPage = new AlertsFramesWindowsPage(DriverFactory.getPage(), DriverFactory.getContext()); 11 | 12 | @When("^user clicks \"([^\"]*)\" navbar option in Alerts, Frame & Windows page$") 13 | public void clickAlertFrameWinNavBar(String navbarOption) { 14 | alertsFramesWindowsPage.clickAlertFrameWinNavBar(navbarOption); 15 | } 16 | 17 | @Then("^verify \"([^\"]*)\" is url of new tab opened in Browser Windows section in Alerts, Frame & Windows page$") 18 | public void verifyNewTabURL(String newTabURL) { 19 | Assert.assertTrue(alertsFramesWindowsPage.verifyNewTabURL(newTabURL)); 20 | } 21 | 22 | @Then("^verify \"([^\"]*)\" is url of new window opened in Browser Windows section in Alerts, Frame & Windows page$") 23 | public void verifyNewWinURL(String newWinURL) { 24 | Assert.assertTrue(alertsFramesWindowsPage.verifyNewWinURL(newWinURL)); 25 | } 26 | 27 | @When("^user enters \"([^\"]*)\" text and accept the alert in Alerts section in Alerts, Frame & Windows page$") 28 | public void enterTextAndAcceptAlert(String alertText) { 29 | alertsFramesWindowsPage.enterTextAndAcceptAlert(alertText); 30 | } 31 | 32 | @Then("^verify \"([^\"]*)\" text is accepted in alert in Alerts section in Alerts, Frame & Windows page$") 33 | public void verifyAlertText(String alertText) { 34 | Assert.assertTrue(alertsFramesWindowsPage.verifyAlertText(alertText)); 35 | } 36 | 37 | @Then("^verify \"([^\"]*)\" as frame content in Frames section in Alerts, Frame & Windows page$") 38 | public void verifyFrameText(String frameText) { 39 | Assert.assertTrue(alertsFramesWindowsPage.verifyFrameText(frameText)); 40 | } 41 | 42 | @Then("^verify Nested Child frame is displayed in Nested Frames section in Alerts, Frame & Windows page$") 43 | public void verifyNestedFrameChildText() { 44 | Assert.assertTrue(alertsFramesWindowsPage.verifyNestedFrameChildText()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/stepdefinitions/ElementsSteps.java: -------------------------------------------------------------------------------- 1 | package stepdefinitions; 2 | 3 | import factory.DriverFactory; 4 | import io.cucumber.java.en.Then; 5 | import io.cucumber.java.en.When; 6 | import org.junit.Assert; 7 | import pages.ElementsPage; 8 | 9 | public class ElementsSteps { 10 | ElementsPage elementsPage = new ElementsPage(DriverFactory.getPage()); 11 | 12 | @When("^user clicks \"([^\"]*)\" navbar option in Elements page$") 13 | public void clickElementNavBar(String navbarOption) { 14 | elementsPage.clickElementNavBar(navbarOption); 15 | } 16 | 17 | @When("^user enters \"([^\"]*)\" in Full Name Edit box in Elements page$") 18 | public void enterFullName(String fullName) { 19 | elementsPage.enterFullName(fullName); 20 | } 21 | 22 | @When("^user clicks Submit in Text Box section in Elements page$") 23 | public void clickSubmit() { 24 | elementsPage.clickSubmit(); 25 | } 26 | 27 | @Then("^verify submitted text is displayed in Text Box section in Elements page$") 28 | public void verifySubmittedText() { 29 | Assert.assertTrue(elementsPage.verifySubmittedText()); 30 | } 31 | 32 | @When("^user clicks on Home checkbox in Check Box section in Elements page$") 33 | public void clickHomeCheckBox() { 34 | elementsPage.clickHomeCheckBox(); 35 | } 36 | 37 | @Then("^verify that \"([^\"]*)\" checkbox selected text is displayed in Check Box section in Elements page$") 38 | public void verifyCheckboxSelectedText(String checkBoxText) { 39 | Assert.assertTrue(elementsPage.verifyCheckboxSelectedText(checkBoxText)); 40 | } 41 | 42 | @Then("^verify that No radio button is disabled in Radio Button section in Elements page$") 43 | public void verifyNoRadioButtonDisabled() { 44 | Assert.assertTrue(elementsPage.verifyNoRadioButtonDisabled()); 45 | } 46 | 47 | @Then("^verify that \"([^\"]*)\" is first column header in Web Tables section in Elements page$") 48 | public void verifyFirstColumnTableHeader(String headerName) { 49 | Assert.assertTrue(elementsPage.verifyFirstColumnTableHeader(headerName)); 50 | } 51 | 52 | @When("^user edits Cierra entry in Web Tables section in Elements page$") 53 | public void editCierraEntry() { 54 | elementsPage.editCierraEntry(); 55 | } 56 | 57 | @Then("^user verifies Registration Form is displayed in Web Tables section in Elements page$") 58 | public void verifyRegistrationForm() { 59 | Assert.assertTrue(elementsPage.verifyRegistrationForm()); 60 | } 61 | 62 | @When("^user clicks on Close button in Registration Form in Web Tables section in Elements page$") 63 | public void registrationFormClose() { 64 | elementsPage.registrationFormClose(); 65 | } 66 | 67 | @When("^user performs \"([^\"]*)\" click in Buttons section in Elements page$") 68 | public void performClick(String clickType) { 69 | elementsPage.performClick(clickType); 70 | } 71 | 72 | @Then("^user verifies \"([^\"]*)\" click success message in Buttons section in Elements page$") 73 | public void verifyClickSuccessMsg(String clickType) { 74 | Assert.assertTrue(elementsPage.verifyClickSuccessMsg(clickType)); 75 | } 76 | 77 | @Then("^verify user is able to download file in Upload and Download section in Elements page$") 78 | public void verifyFileDownload() { 79 | elementsPage.verifyFileDownload(); 80 | } 81 | 82 | @Then("^user uploads \"([^\"]*)\" file in Upload and Download section in Elements page$") 83 | public void performFileUpload(String fileName) { 84 | elementsPage.performFileUpload(fileName); 85 | } 86 | 87 | @Then("^verify \"([^\"]*)\" is uploaded successfully in Upload and Download section in Elements page$") 88 | public void verifyFileUpload(String fileName) { 89 | Assert.assertTrue(elementsPage.verifyFileUpload(fileName)); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/stepdefinitions/InteractionsSteps.java: -------------------------------------------------------------------------------- 1 | package stepdefinitions; 2 | 3 | import factory.DriverFactory; 4 | import io.cucumber.java.en.Then; 5 | import io.cucumber.java.en.When; 6 | import org.junit.Assert; 7 | import pages.ElementsPage; 8 | import pages.InteractionsPage; 9 | 10 | public class InteractionsSteps { 11 | InteractionsPage interactionsPage = new InteractionsPage(DriverFactory.getPage()); 12 | 13 | @When("^user clicks \"([^\"]*)\" navbar option in Interactions page$") 14 | public void clickElementNavBar(String navbarOption) { 15 | interactionsPage.clickInteractionsNavBar(navbarOption); 16 | } 17 | 18 | @When("^user performs drag and drop in Droppable section in Interactions page$") 19 | public void performDragAndDrop() { 20 | interactionsPage.performDragAndDrop(); 21 | } 22 | 23 | @Then("^verify \"([^\"]*)\" text is displayed after successful drag and drop in Droppable section in Interactions page$") 24 | public void verifyDragAndDrop(String dropText) { 25 | Assert.assertTrue(interactionsPage.verifyDragAndDrop(dropText)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/stepdefinitions/LoginSteps.java: -------------------------------------------------------------------------------- 1 | package stepdefinitions; 2 | 3 | import factory.DriverFactory; 4 | import io.cucumber.java.en.Given; 5 | import io.cucumber.java.en.Then; 6 | import io.cucumber.java.en.When; 7 | import org.junit.Assert; 8 | import pages.LoginPage; 9 | import utils.WebActions; 10 | 11 | public class LoginSteps { 12 | LoginPage loginPage = new LoginPage(DriverFactory.getPage()); 13 | 14 | @Given("^user navigates to \"([^\"]*)\"$") 15 | public void navigateToUrl(String url) { 16 | loginPage.navigateToUrl(url); 17 | } 18 | 19 | @When("^user enters \"([^\"]*)\" username$") 20 | public void enterUsername(String username) { 21 | loginPage.enterUsername(username); 22 | } 23 | 24 | @When("^user enters \"([^\"]*)\" password$") 25 | public void enterPassword(String password) { 26 | loginPage.enterPassword(password); 27 | } 28 | 29 | @When("^user clicks Login button$") 30 | public void clickLogin() { 31 | loginPage.clickLogin(); 32 | } 33 | 34 | @When("^user clicks on \"([^\"]*)\" icon in main page") 35 | public void clickOnIcon(String iconName) { 36 | loginPage.clickOnIcon(iconName); 37 | } 38 | 39 | @Then("verify that user is logged in and navigated to Profile page") 40 | public void verifyProfilePage() { 41 | Assert.assertTrue(loginPage.verifyProfilePage()); 42 | } 43 | 44 | @Then("^user verifies data as \"([^\"]*)\" in \"([^\"]*)\" row and \"([^\"]*)\" column from \"([^\"]*)\" sheet in \"([^\"]*)\" file") 45 | public void clickOnIcon(String expectedValue, int rowNum, int colNum, String sheetName, String fileName) { 46 | String actualValue = WebActions.getRowColValue(fileName, sheetName, rowNum, colNum); 47 | Assert.assertEquals(expectedValue, actualValue); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/stepdefinitions/WidgetsSteps.java: -------------------------------------------------------------------------------- 1 | package stepdefinitions; 2 | 3 | import factory.DriverFactory; 4 | import io.cucumber.java.en.Then; 5 | import io.cucumber.java.en.When; 6 | import org.junit.Assert; 7 | import pages.WidgetsPage; 8 | 9 | public class WidgetsSteps { 10 | WidgetsPage widgetsPage = new WidgetsPage(DriverFactory.getPage()); 11 | 12 | @When("^user clicks \"([^\"]*)\" navbar option in Widgets page$") 13 | public void clickElementNavBar(String navbarOption) { 14 | widgetsPage.clickWidgetsNavBar(navbarOption); 15 | } 16 | 17 | @When("^user enters \"([^\"]*)\" in Single color name edit box in Auto Complete section in Widgets page$") 18 | public void fillAutocompleteTextField(String textValue) { 19 | widgetsPage.fillAutocompleteTextField(textValue); 20 | } 21 | 22 | @Then("^verify Blue color is selected in Single color name in Auto Complete section in Widgets page$") 23 | public void verifyBlueColourSelected() { 24 | Assert.assertTrue(widgetsPage.verifyBlueColourSelected()); 25 | } 26 | 27 | @When("^user hovers over button in Tool Tips section in Widgets page$") 28 | public void hoverOverButton() { 29 | widgetsPage.hoverOverButton(); 30 | } 31 | 32 | @Then("^verify \"([^\"]*)\" tooltip is displayed in Tool Tips section in Widgets page$") 33 | public void verifyTooltip(String toolTip) { 34 | Assert.assertTrue(widgetsPage.verifyTooltip(toolTip)); 35 | } 36 | 37 | @When("^user selects \"([^\"]*)\" in Old Style Select Menu in Select Menu section in Widgets page$") 38 | public void oldStyleSelectColour(String colorName) { 39 | widgetsPage.oldStyleSelectColour(colorName); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/testrunner/ReRunner.java: -------------------------------------------------------------------------------- 1 | package testrunner; 2 | 3 | import io.cucumber.junit.Cucumber; 4 | import io.cucumber.junit.CucumberOptions; 5 | import org.junit.runner.RunWith; 6 | 7 | @RunWith(Cucumber.class) 8 | @CucumberOptions( 9 | // Rerun failed tests from rerun.txt file 10 | features = {"@target/rerun.txt"}, 11 | glue = {"stepdefinitions", "hooks"}, 12 | plugin = {"pretty", 13 | "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:", 14 | "rerun:target/rerun.txt" 15 | } 16 | ) 17 | 18 | 19 | public class ReRunner { 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/testrunner/TestRunner.java: -------------------------------------------------------------------------------- 1 | package testrunner; 2 | 3 | 4 | import io.cucumber.junit.Cucumber; 5 | import io.cucumber.junit.CucumberOptions; 6 | import org.junit.runner.RunWith; 7 | 8 | @RunWith(Cucumber.class) 9 | @CucumberOptions( 10 | // Rerun failed tests from rerun.txt file 11 | features = {"src/test/resources/features/"}, 12 | glue = {"stepdefinitions", "hooks"}, 13 | plugin = {"pretty", 14 | "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:", 15 | "rerun:target/rerun.txt" // Save Failed test scenarios in rerun.txt file 16 | } 17 | ) 18 | 19 | public class TestRunner { 20 | } 21 | -------------------------------------------------------------------------------- /src/test/resources/config/config.properties: -------------------------------------------------------------------------------- 1 | browser=chrome 2 | headless=false 3 | url=https://demoqa.com/ 4 | timeout=60 5 | adminUsername=demouat@gmail.com 6 | adminPassword=RGVtb3VhdEAwOQ== -------------------------------------------------------------------------------- /src/test/resources/extent-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | dark 9 | 10 | 11 | 12 | 13 | UTF-8 14 | 15 | 16 | 17 | 18 | http 19 | 20 | Tools QA Report 21 | 22 | 23 | Tools QA Report 24 | 25 | 26 | 27 | 28 | bottom 29 | 30 | 31 | 32 | 33 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/test/resources/extent.properties: -------------------------------------------------------------------------------- 1 | extent.reporter.spark.start=true 2 | extent.reporter.spark.out=target/HTMLReport/ToolsQA.html 3 | extent.reporter.spark.config=src/test/resources/extent-config.xml 4 | screenshot.dir=target/ 5 | screenshot.rel.path=../ 6 | extent.reporter.pdf.start=true 7 | extent.reporter.pdf.out=target/PdfReport/ToolsQA.pdf 8 | extent.reporter.spark.vieworder=dashboard,test,category,exception,author,device,log 9 | systeminfo.os=Fedora 10 | systeminfo.user=Akshay 11 | systeminfo.build=1.0.0 12 | systeminfo.AppName=ToolsQA -------------------------------------------------------------------------------- /src/test/resources/features/AlertsFrameWindows.feature: -------------------------------------------------------------------------------- 1 | Feature: Verify Alerts, Frame & Windows Page 2 | 3 | @smoke 4 | Scenario: Verify User is able to handle pop up windows, frames and alerts 5 | Given user navigates to "url" 6 | When user clicks on "Alerts, Frame & Windows" icon in main page 7 | And user clicks "Browser Windows" navbar option in Alerts, Frame & Windows page 8 | Then verify "https://demoqa.com/sample" is url of new tab opened in Browser Windows section in Alerts, Frame & Windows page 9 | And verify "https://demoqa.com/sample" is url of new window opened in Browser Windows section in Alerts, Frame & Windows page 10 | When user clicks "Alerts" navbar option in Alerts, Frame & Windows page 11 | And user enters "Hello" text and accept the alert in Alerts section in Alerts, Frame & Windows page 12 | Then verify "Hello" text is accepted in alert in Alerts section in Alerts, Frame & Windows page 13 | When user clicks "Frames" navbar option in Alerts, Frame & Windows page 14 | Then verify "This is a sample page" as frame content in Frames section in Alerts, Frame & Windows page 15 | When user clicks "Nested Frames" navbar option in Alerts, Frame & Windows page 16 | Then verify Nested Child frame is displayed in Nested Frames section in Alerts, Frame & Windows page -------------------------------------------------------------------------------- /src/test/resources/features/Elements.feature: -------------------------------------------------------------------------------- 1 | Feature: Verify the functionalities of Elements page 2 | 3 | @smoke 4 | Scenario: Verify User is able to perform actions on Web Elements in Elements page 5 | Given user navigates to "url" 6 | When user clicks on "Elements" icon in main page 7 | And user clicks "Text Box" navbar option in Elements page 8 | And user enters "AutoTest" in Full Name Edit box in Elements page 9 | And user clicks Submit in Text Box section in Elements page 10 | Then verify submitted text is displayed in Text Box section in Elements page 11 | When user clicks "Check Box" navbar option in Elements page 12 | And user clicks on Home checkbox in Check Box section in Elements page 13 | Then verify that "home" checkbox selected text is displayed in Check Box section in Elements page 14 | When user clicks "Radio Button" navbar option in Elements page 15 | Then verify that No radio button is disabled in Radio Button section in Elements page 16 | When user clicks "Web Tables" navbar option in Elements page 17 | Then verify that "First Name" is first column header in Web Tables section in Elements page 18 | When user edits Cierra entry in Web Tables section in Elements page 19 | Then user verifies Registration Form is displayed in Web Tables section in Elements page 20 | When user clicks on Close button in Registration Form in Web Tables section in Elements page 21 | And user clicks "Buttons" navbar option in Elements page 22 | And user performs "double" click in Buttons section in Elements page 23 | Then user verifies "double" click success message in Buttons section in Elements page 24 | When user performs "right" click in Buttons section in Elements page 25 | Then user verifies "right" click success message in Buttons section in Elements page 26 | And user clicks "Upload and Download" navbar option in Elements page 27 | Then verify user is able to download file in Upload and Download section in Elements page 28 | When user uploads "sampleFile.jpeg" file in Upload and Download section in Elements page 29 | Then verify "sampleFile.jpeg" is uploaded successfully in Upload and Download section in Elements page -------------------------------------------------------------------------------- /src/test/resources/features/ExcelReader.feature: -------------------------------------------------------------------------------- 1 | Feature: Read from Excel File 2 | 3 | Scenario: Get value from specified Row and Column from xlsx file 4 | Then user verifies data as "John" in "1" row and "1" column from "Sheet1" sheet in "Students" file -------------------------------------------------------------------------------- /src/test/resources/features/Interactions.feature: -------------------------------------------------------------------------------- 1 | Feature: Verify Interactions Page 2 | 3 | @smoke 4 | Scenario: Verify User is able perform Drag and Drop 5 | Given user navigates to "url" 6 | When user clicks on "Interactions" icon in main page 7 | And user clicks "Droppable" navbar option in Interactions page 8 | And user performs drag and drop in Droppable section in Interactions page 9 | Then verify "Dropped" text is displayed after successful drag and drop in Droppable section in Interactions page -------------------------------------------------------------------------------- /src/test/resources/features/Login.feature: -------------------------------------------------------------------------------- 1 | Feature: Login Page feature 2 | 3 | @smoke 4 | Scenario: Verify User is able to login to Book Store with correct credentials 5 | Given user navigates to "url" 6 | When user clicks on "Book Store Application" icon in main page 7 | And user clicks Login button 8 | And user enters "adminUsername" username 9 | And user enters "adminPassword" password 10 | And user clicks Login button 11 | Then verify that user is logged in and navigated to Profile page -------------------------------------------------------------------------------- /src/test/resources/features/Widgets.feature: -------------------------------------------------------------------------------- 1 | Feature: Verify Widgets Page 2 | 3 | @smoke 4 | Scenario: Verify User is interact with Widgets 5 | Given user navigates to "url" 6 | When user clicks on "Widgets" icon in main page 7 | And user clicks "Auto Complete" navbar option in Widgets page 8 | And user enters "Bl" in Single color name edit box in Auto Complete section in Widgets page 9 | Then verify Blue color is selected in Single color name in Auto Complete section in Widgets page 10 | When user clicks "Tool Tips" navbar option in Widgets page 11 | And user hovers over button in Tool Tips section in Widgets page 12 | Then verify "You hovered over the Button" tooltip is displayed in Tool Tips section in Widgets page 13 | When user clicks "Select Menu" navbar option in Widgets page 14 | And user selects "Aqua" in Old Style Select Menu in Select Menu section in Widgets page --------------------------------------------------------------------------------