├── settings.gradle ├── src └── test │ ├── resources │ ├── cucumber.properties │ ├── files │ │ ├── testdata.xlsx │ │ ├── images │ │ │ ├── red_icon.png │ │ │ ├── allure_gif.gif │ │ │ ├── green_icon.png │ │ │ ├── testPhoto.jpg │ │ │ ├── linkedin_icon.png │ │ │ ├── readme_banner.jpg │ │ │ ├── slack_bot_fail.png │ │ │ └── slack_bot_pass.png │ │ └── backup-testdata.xlsx │ ├── invalidEmails.properties │ ├── allure.properties │ ├── xml_runners │ │ ├── main_runner │ │ │ └── TestNG-Runner.xml │ │ ├── TestNG-WebAPI.xml │ │ ├── TestNG-POC.xml │ │ └── TestNG-WebAPP.xml │ ├── errorValidators.properties │ ├── features │ │ ├── SocialMedia.feature │ │ ├── Authentication.feature │ │ ├── Shopping-LoggedUser.feature │ │ ├── SearchBox.feature │ │ ├── CustomerService.feature │ │ ├── Registration.feature │ │ └── RegistrationValidators.feature │ └── logback-test.xml │ └── java │ ├── com │ ├── buildSeleniumGrid │ │ ├── LocalHub.java │ │ ├── LocalNode.java │ │ └── SeleniumGridRunner.java │ ├── pages │ │ ├── AccountDetailsPage.java │ │ ├── SocialMediaPage.java │ │ ├── SearchPage.java │ │ ├── base │ │ │ └── BasePage.java │ │ ├── MainPage.java │ │ ├── AuthenticationPage.java │ │ ├── CustomerServicePage.java │ │ ├── ProductDetailsPage.java │ │ ├── RegistrationPage.java │ │ └── ShoppingCartSummaryPage.java │ ├── buildListeners │ │ ├── TestNGAnnotationTransformer.java │ │ ├── TestNGRetry.java │ │ └── TestNGListener.java │ ├── steps │ │ ├── hooks │ │ │ ├── API_Hooks.java │ │ │ └── WEB_Hooks.java │ │ ├── AuthenticationPageSteps.java │ │ ├── MainPageSteps.java │ │ ├── SocialMediaPageSteps.java │ │ ├── SearchPageSteps.java │ │ └── CustomerServicePageSteps.java │ ├── CucumberRunner.java │ ├── buildSettings │ │ ├── ExcelEnvironment.java │ │ ├── MessageBuilder.java │ │ ├── ContextInjection.java │ │ ├── TestCommons.java │ │ └── TestEnvironment.java │ ├── DriverFactory.java │ └── buildLogger │ │ └── SlackLogger.java │ └── tests │ ├── WebAPI │ └── API_Tests.java │ ├── POC │ └── POC_Tests.java │ └── WebAPP │ ├── SocialMedia_Tests.java │ ├── Authentication_Tests.java │ ├── ShoppingLoggedUser_Tests.java │ ├── SearchBox_Tests.java │ └── Registration_Tests.java ├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .travis └── deploy.sh ├── LICENSE.md ├── gradlew.bat ├── gradlew ├── .travis.yml └── README.md /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Test_Automation-automationpractice.com' -------------------------------------------------------------------------------- /src/test/resources/cucumber.properties: -------------------------------------------------------------------------------- 1 | cucumber.publish.enabled=true 2 | cucumber.publish.quiet=true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | .idea/ 3 | allure-report/ 4 | build/ 5 | logs/ 6 | screenshots/ 7 | target/ 8 | *.txt -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/test/resources/files/testdata.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/testdata.xlsx -------------------------------------------------------------------------------- /src/test/resources/files/images/red_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/images/red_icon.png -------------------------------------------------------------------------------- /src/test/resources/files/backup-testdata.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/backup-testdata.xlsx -------------------------------------------------------------------------------- /src/test/resources/files/images/allure_gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/images/allure_gif.gif -------------------------------------------------------------------------------- /src/test/resources/files/images/green_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/images/green_icon.png -------------------------------------------------------------------------------- /src/test/resources/files/images/testPhoto.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/images/testPhoto.jpg -------------------------------------------------------------------------------- /src/test/resources/files/images/linkedin_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/images/linkedin_icon.png -------------------------------------------------------------------------------- /src/test/resources/files/images/readme_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/images/readme_banner.jpg -------------------------------------------------------------------------------- /src/test/resources/files/images/slack_bot_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/images/slack_bot_fail.png -------------------------------------------------------------------------------- /src/test/resources/files/images/slack_bot_pass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/HEAD/src/test/resources/files/images/slack_bot_pass.png -------------------------------------------------------------------------------- /src/test/resources/invalidEmails.properties: -------------------------------------------------------------------------------- 1 | invalidEmails=!#$%&*+-/=?^_{}~example.org, üñîçø"ðé@ü"ñîçøðé.com, Abc.example.com, A@b@c@example.com, a"b(c)d,e:f;gi[jk]l@example.com, just"not"right@example.com -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /src/test/resources/allure.properties: -------------------------------------------------------------------------------- 1 | allure.link.issue.pattern=https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE/issue/{} 2 | allure.link.tms.pattern=https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE/{} 3 | allure.results.directory=build/allure-results -------------------------------------------------------------------------------- /src/test/resources/xml_runners/main_runner/TestNG-Runner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.travis/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | git clone --single-branch --branch gh-pages https://kamil-nowocin:$GITHUB_TOKEN@github.com/kamil-nowocin/Test_Automation-automationpractice target/github-pages 4 | sleep 5 5 | cp -R target/github-pages/history build/allure-results 6 | cd build 7 | allure generate --clean 8 | sleep 10 9 | cd .. 10 | cp -R build/allure-report/* target/github-pages/ 11 | cd target/github-pages/ 12 | git config user.name "Travis CI" 13 | git config user.email "deploy@travis-ci.org" 14 | git add -A 15 | git commit -m "Auto deploy from Travis CI $TRAVIS_BUILD_NUMBER" 16 | git push origin gh-pages -------------------------------------------------------------------------------- /src/test/resources/errorValidators.properties: -------------------------------------------------------------------------------- 1 | error-FirstName=firstname is required. 2 | error-LastName=lastname is required. 3 | error-Email=email is required. 4 | error-Password=passwd is required. 5 | error-Address=address1 is required. 6 | error-City=city is required. 7 | error-State=This country requires you to choose a State. 8 | error-PostalCode=The Zip/Postal code you've entered is invalid. It must follow this format: 00000 9 | error-Country=Country is invalid 10 | error-MobilePhone=You must register at least one phone number. 11 | error-EmailAlias=alias is required. 12 | error-oneError=There is 1 error -------------------------------------------------------------------------------- /src/test/resources/xml_runners/TestNG-WebAPI.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/test/java/com/buildSeleniumGrid/LocalHub.java: -------------------------------------------------------------------------------- 1 | package com.buildSeleniumGrid; 2 | 3 | import org.openqa.grid.internal.utils.configuration.GridHubConfiguration; 4 | import org.openqa.grid.web.Hub; 5 | 6 | /** 7 | * Test_Automation-automationpractice 8 | * 9 | * @author kamil.nowocin 10 | **/ 11 | 12 | public class LocalHub { 13 | 14 | private static Hub hub; 15 | 16 | public LocalHub(GridHubConfiguration gridHubConfiguration) { 17 | hub = new Hub(gridHubConfiguration); 18 | } 19 | 20 | public void start() { 21 | hub.start(); 22 | } 23 | 24 | public void stop() { 25 | hub.stop(); 26 | } 27 | } -------------------------------------------------------------------------------- /src/test/java/com/pages/AccountDetailsPage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.pages.base.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | /** 9 | * Test_Automation-automationpractice 10 | * 11 | * @author kamil.nowocin 12 | **/ 13 | 14 | public class AccountDetailsPage extends BasePage { 15 | 16 | //VIEW// 17 | @FindBy(how = How.XPATH, using = "//p[@class='info-account']") 18 | public WebElement myAccountDetailsDashboard; 19 | 20 | public AccountDetailsPage() { 21 | super("/index.php"); 22 | } 23 | } -------------------------------------------------------------------------------- /src/test/java/com/buildListeners/TestNGAnnotationTransformer.java: -------------------------------------------------------------------------------- 1 | package com.buildListeners; 2 | 3 | import org.testng.IAnnotationTransformer; 4 | import org.testng.annotations.ITestAnnotation; 5 | 6 | import java.lang.reflect.Constructor; 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * Test_Automation-automationpractice 11 | * 12 | * @author kamil.nowocin 13 | **/ 14 | 15 | public class TestNGAnnotationTransformer implements IAnnotationTransformer { 16 | 17 | @Override 18 | public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { 19 | annotation.setRetryAnalyzer(TestNGRetry.class); 20 | } 21 | } -------------------------------------------------------------------------------- /src/test/resources/xml_runners/TestNG-POC.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/test/java/com/pages/SocialMediaPage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.pages.base.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | /** 9 | * Test_Automation-automationpractice 10 | * 11 | * @author kamil.nowocin 12 | **/ 13 | 14 | public class SocialMediaPage extends BasePage { 15 | 16 | //BUTTONS & INPUTS & DROPDOWN// 17 | @FindBy(how = How.XPATH, using = "//*[@class=\"facebook\"]") 18 | public WebElement facebookButton; 19 | 20 | @FindBy(how = How.XPATH, using = "//*[@class=\"twitter\"]") 21 | public WebElement twitterButton; 22 | 23 | @FindBy(how = How.XPATH, using = "//*[@class=\"youtube\"]") 24 | public WebElement youtubeButton; 25 | 26 | @FindBy(how = How.XPATH, using = "//*[@class=\"google-plus\"]") 27 | public WebElement googleButton; 28 | 29 | public SocialMediaPage() { 30 | super("/index.php"); 31 | } 32 | } -------------------------------------------------------------------------------- /src/test/resources/xml_runners/TestNG-WebAPP.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/test/java/com/buildListeners/TestNGRetry.java: -------------------------------------------------------------------------------- 1 | package com.buildListeners; 2 | 3 | import com.buildSettings.TestEnvironment; 4 | import org.testng.IRetryAnalyzer; 5 | import org.testng.ITestResult; 6 | 7 | /** 8 | * Test_Automation-automationpractice 9 | * 10 | * @author kamil.nowocin 11 | **/ 12 | 13 | public class TestNGRetry extends TestEnvironment implements IRetryAnalyzer { 14 | 15 | private int retryStatus = 0; 16 | 17 | @Override 18 | public boolean retry(ITestResult iTestResult) { 19 | if (!iTestResult.isSuccess()) { 20 | int retryLimit = 1; 21 | if (retryStatus < retryLimit) { 22 | retryStatus++; 23 | iTestResult.setStatus(ITestResult.FAILURE); 24 | logger.info(String.format(ANSI_RED + "TEST RETRY (%d/" + retryLimit + "): %S" + ANSI_RESET, retryStatus, 25 | iTestResult.getMethod().getDescription())); 26 | return true; 27 | } 28 | } else { 29 | iTestResult.setStatus(ITestResult.SUCCESS); 30 | } 31 | return false; 32 | } 33 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Kamil Nowocin 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. -------------------------------------------------------------------------------- /src/test/java/com/buildSeleniumGrid/LocalNode.java: -------------------------------------------------------------------------------- 1 | package com.buildSeleniumGrid; 2 | 3 | import org.openqa.grid.internal.utils.SelfRegisteringRemote; 4 | import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration; 5 | import org.openqa.selenium.remote.server.SeleniumServer; 6 | 7 | /** 8 | * Test_Automation-automationpractice 9 | * 10 | * @author kamil.nowocin 11 | **/ 12 | 13 | public class LocalNode { 14 | 15 | private final SelfRegisteringRemote selfRegisteringRemoteNode; 16 | 17 | public LocalNode(GridNodeConfiguration gridNodeConfiguration) { 18 | selfRegisteringRemoteNode = new SelfRegisteringRemote(gridNodeConfiguration); 19 | SeleniumServer seleniumServer = new SeleniumServer(selfRegisteringRemoteNode.getConfiguration()); 20 | selfRegisteringRemoteNode.setRemoteServer(seleniumServer); 21 | } 22 | 23 | public void start() { 24 | if (selfRegisteringRemoteNode.startRemoteServer()) { 25 | selfRegisteringRemoteNode.sendRegistrationRequest(); 26 | } 27 | } 28 | 29 | public void stop() { 30 | selfRegisteringRemoteNode.stopRemoteServer(); 31 | } 32 | } -------------------------------------------------------------------------------- /src/test/java/com/buildSeleniumGrid/SeleniumGridRunner.java: -------------------------------------------------------------------------------- 1 | package com.buildSeleniumGrid; 2 | 3 | import org.openqa.grid.internal.utils.configuration.GridHubConfiguration; 4 | import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * Test_Automation-automationpractice 10 | * 11 | * @author kamil.nowocin 12 | **/ 13 | 14 | public class SeleniumGridRunner { 15 | 16 | public static void main(String[] args) throws InterruptedException { 17 | GridHubConfiguration gridHubConfiguration = new GridHubConfiguration(); 18 | gridHubConfiguration.port = 4444; 19 | LocalHub localHub = new LocalHub(gridHubConfiguration); 20 | localHub.start(); 21 | 22 | GridNodeConfiguration gridNodeConfiguration = new GridNodeConfiguration(); 23 | gridNodeConfiguration.port = 5555; 24 | LocalNode localNode = new LocalNode(gridNodeConfiguration); 25 | localNode.start(); 26 | 27 | //TODO - Better configuration of start & stop 28 | TimeUnit.SECONDS.sleep(1000); 29 | 30 | localNode.stop(); 31 | localHub.stop(); 32 | } 33 | } -------------------------------------------------------------------------------- /src/test/java/com/steps/hooks/API_Hooks.java: -------------------------------------------------------------------------------- 1 | package com.steps.hooks; 2 | 3 | import com.DriverFactory; 4 | import com.buildSettings.ExcelEnvironment; 5 | import com.buildSettings.MessageBuilder; 6 | import org.slf4j.MDC; 7 | import org.testng.ITestListener; 8 | import org.testng.ITestResult; 9 | import org.testng.annotations.AfterMethod; 10 | import org.testng.annotations.BeforeMethod; 11 | import org.testng.annotations.BeforeTest; 12 | 13 | /** 14 | * Test_Automation-automationpractice 15 | * 16 | * @author kamil.nowocin 17 | **/ 18 | 19 | public class API_Hooks extends DriverFactory implements ITestListener { 20 | 21 | private final ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 22 | 23 | @BeforeTest(alwaysRun = true, description = "Setting up Excel File") 24 | public void dataSetup() { 25 | excelEnvironment.setExcelSheet(ExcelEnvironment.TEST_DATA_EXCEL_SHEET_NAME); 26 | } 27 | 28 | @BeforeMethod(alwaysRun = true, description = "Setting up Test Class") 29 | public void beforeTest(ITestResult iTestResult) { 30 | MDC.put("testid", MessageBuilder.getTestDescription(iTestResult)); 31 | } 32 | 33 | @AfterMethod(alwaysRun = true, description = "Teardown Test Class") 34 | public void afterTest() { 35 | MDC.remove("testid"); 36 | } 37 | } -------------------------------------------------------------------------------- /src/test/java/com/pages/SearchPage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.pages.base.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Test_Automation-automationpractice 12 | * 13 | * @author kamil.nowocin 14 | **/ 15 | 16 | public class SearchPage extends BasePage { 17 | 18 | //VIEW// 19 | @FindBy(how = How.XPATH, using = "//span[@class='heading-counter']") 20 | public WebElement searchResultsNumber; 21 | 22 | @FindBy(how = How.XPATH, using = "//div[@id='center_column']//p") 23 | public WebElement noResultsWereFoundHeader; 24 | 25 | //BUTTONS & INPUTS & DROPDOWN// 26 | @FindBy(how = How.XPATH, using = "//select[@id='selectProductSort']") 27 | public WebElement sortByDropdown; 28 | 29 | @FindBy(how = How.XPATH, using = "//div[@id='uniform-selectProductSort']//span") 30 | public WebElement readSortByDropdown; 31 | 32 | @FindBy(how = How.XPATH, using = "//div[@class='right-block']//a[@class='product-name']") 33 | public List productNames; 34 | 35 | @FindBy(how = How.XPATH, using = "//div[@class='right-block']//div[@class='content_price']//span[@class='price product-price']") 36 | public List productPrices; 37 | 38 | public SearchPage() { 39 | super("/index.php"); 40 | } 41 | } -------------------------------------------------------------------------------- /src/test/java/com/pages/base/BasePage.java: -------------------------------------------------------------------------------- 1 | package com.pages.base; 2 | 3 | import com.DriverFactory; 4 | import com.buildSettings.TestCommons; 5 | import com.buildSettings.TestEnvironment; 6 | import org.openqa.selenium.support.PageFactory; 7 | import org.openqa.selenium.support.ui.LoadableComponent; 8 | 9 | /** 10 | * Test_Automation-automationpractice 11 | * 12 | * @author kamil.nowocin 13 | **/ 14 | 15 | public abstract class BasePage> extends LoadableComponent { 16 | 17 | private final String pageURL; 18 | 19 | protected BasePage(String pageURL) { 20 | this.pageURL = pageURL; 21 | //PageFactory.initElements(new AjaxElementLocatorFactory(DriverFactory.getDriver(), TIMEOUT), this); 22 | PageFactory.initElements(DriverFactory.getDriver(), this); 23 | } 24 | 25 | @Override 26 | public void load() { 27 | if (pageURL.startsWith("http://") || pageURL.startsWith("https://")) { 28 | DriverFactory.getDriver().get(pageURL); 29 | } else { 30 | DriverFactory.getDriver().get(TestEnvironment.HOME_URL + pageURL); 31 | } 32 | } 33 | 34 | @Override 35 | public void isLoaded() throws Error { 36 | if (!DriverFactory.getDriver().getCurrentUrl().contains(pageURL) && TestCommons.isPageReady()) { 37 | throw new Error("Automationpractice website isn't correctly loaded!"); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/test/java/tests/WebAPI/API_Tests.java: -------------------------------------------------------------------------------- 1 | package tests.WebAPI; 2 | 3 | import com.buildListeners.TestNGListener; 4 | import com.buildSettings.ExcelEnvironment; 5 | import com.steps.hooks.API_Hooks; 6 | import io.qameta.allure.*; 7 | import io.restassured.RestAssured; 8 | import org.testng.annotations.Listeners; 9 | import org.testng.annotations.Test; 10 | 11 | import static io.restassured.RestAssured.given; 12 | 13 | /** 14 | * Test_Automation-automationpractice 15 | * 16 | * @author kamil.nowocin 17 | **/ 18 | 19 | @Epic("API Tests") 20 | @Feature("HTTP Statuses") 21 | @Listeners({TestNGListener.class}) 22 | public class API_Tests extends API_Hooks { 23 | 24 | private String restHomeURL() { 25 | return RestAssured.baseURI = "http://automationpractice.com/"; 26 | } 27 | 28 | @Issue("TAP/API-0001") 29 | @TmsLink("JIRA-000") 30 | @Story("HTTP STATUSES") 31 | @Owner("Kamil Nowocin") 32 | @Severity(SeverityLevel.BLOCKER) 33 | @Description("[API]/[1] As a user I would like to check availability of automationpractice.com") 34 | @Test(description = "[API]/[1] I would like to check availability of automationpractice.com", 35 | priority = 0) 36 | public void test_1() throws Throwable { 37 | //ARRANGE// 38 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 39 | 40 | excelEnvironment.saveTestResultsXLSX(45); 41 | 42 | //ACT// 43 | given().when().get(restHomeURL()).then().assertThat().statusCode(200); 44 | } 45 | } -------------------------------------------------------------------------------- /src/test/resources/features/SocialMedia.feature: -------------------------------------------------------------------------------- 1 | #/** 2 | #* Test_Automation-automationpractice 3 | #* 4 | #* @author kamil.nowocin 5 | #**/ 6 | 7 | @socialMedia 8 | Feature: As a user I would like to be redirected to social media pages from automationpractice.com 9 | #--------------------------------------------------------------------------------# 10 | # [UserStory] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-777 # 11 | #--------------------------------------------------------------------------------# 12 | 13 | Background: Navigate to automationpractice.com website 14 | Given I open home page 15 | 16 | #--------------------------------------------------------------------------------# 17 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0041 18 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0042 19 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0043 20 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0044 21 | @non-smoke @minor @regression 22 | Scenario Outline:[US-777]/[1] I click on social media "" logo 23 | Given I can see automationpractice.com website 24 | When I scroll the website until I can see "" logo 25 | And I click on "" logo button 26 | Then I am redirected to Selenium "" profile 27 | 28 | Examples: SCENARIO OUTLINE DATA 29 | | platform | 30 | | Facebook | 31 | | Twitter | 32 | | YouTube | 33 | | Google | -------------------------------------------------------------------------------- /src/test/java/tests/POC/POC_Tests.java: -------------------------------------------------------------------------------- 1 | package tests.POC; 2 | 3 | import com.buildListeners.TestNGListener; 4 | import com.buildSettings.ExcelEnvironment; 5 | import com.steps.hooks.API_Hooks; 6 | import io.qameta.allure.*; 7 | import org.apache.poi.xssf.usermodel.XSSFRow; 8 | import org.testng.Assert; 9 | import org.testng.annotations.Listeners; 10 | import org.testng.annotations.Parameters; 11 | import org.testng.annotations.Test; 12 | 13 | /** 14 | * Test_Automation-automationpractice 15 | * 16 | * @author kamil.nowocin 17 | **/ 18 | 19 | @Epic("POC Tests") 20 | @Feature("POC Tests") 21 | @Listeners({TestNGListener.class}) 22 | public class POC_Tests extends API_Hooks { 23 | 24 | @Step("Some POC step") 25 | public void testSteps(XSSFRow row) { 26 | System.out.println("DATA SET 1: " + row.getCell(5).toString()); 27 | System.out.println("DATA SET 2: " + row.getCell(7).toString()); 28 | } 29 | 30 | @Issue("TAP-POC") 31 | @TmsLink("POC-LINK") 32 | @Story("POC Tests") 33 | @Owner("Kamil Nowocin") 34 | @Severity(SeverityLevel.MINOR) 35 | @Description("[POC]/[1]As a developer I'd like to see working POC with .xlsx file") 36 | @Test(description = "[POC]/[1]As a developer I'd like to see working POC with .xlsx file", 37 | priority = 0) 38 | @Parameters({"Parameter 1", "Parameter 2", "Parameter 3"}) 39 | public void excelTest() throws Throwable { 40 | //ARRANGE// 41 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 42 | 43 | excelEnvironment.saveTestResultsXLSX(50); 44 | 45 | //ACT// 46 | testSteps(excelEnvironment.getRowData(1)); 47 | 48 | //ASSERT// 49 | Assert.fail(); 50 | } 51 | } -------------------------------------------------------------------------------- /src/test/java/com/pages/MainPage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.buildSettings.TestEnvironment; 4 | import com.pages.base.BasePage; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | import org.openqa.selenium.support.How; 8 | 9 | /** 10 | * Test_Automation-automationpractice 11 | * 12 | * @author kamil.nowocin 13 | **/ 14 | 15 | public class MainPage extends BasePage { 16 | 17 | //VIEW// 18 | @FindBy(how = How.XPATH, using = "//a[@class='account']//span") 19 | public WebElement currentLoggedUserName; 20 | 21 | //BUTTONS & INPUTS & DROPDOWN// 22 | @FindBy(how = How.XPATH, using = "//a[@class='login']") 23 | public WebElement signInButton; 24 | 25 | @FindBy(how = How.XPATH, using = "//div[@id='contact-link']") 26 | public WebElement contactUsButton; 27 | 28 | @FindBy(how = How.XPATH, using = "//input[@class='search_query form-control ac_input']") 29 | public WebElement searchBoxInput; 30 | 31 | @FindBy(how = How.XPATH, using = "//form[@id='searchbox']//button[@type='submit']") 32 | public WebElement searchBoxSubmit; 33 | 34 | //SUB-MENU// 35 | @FindBy(how = How.XPATH, using = "//li//a[@title='Women' and not(img)]") 36 | public WebElement subMenuWomen; 37 | 38 | @FindBy(how = How.XPATH, using = "(//li//a[@title='Dresses' and not(img)])[2]") 39 | public WebElement subMenuDresses; 40 | 41 | @FindBy(how = How.XPATH, using = "(//li//a[@title='T-shirts' and not(img)])[2]") 42 | public WebElement subMenuTshirts; 43 | 44 | @FindBy(how = How.XPATH, using = "//span[@class='cat-name']") 45 | public WebElement subMenuChosenCategory; 46 | 47 | public MainPage() { 48 | super(TestEnvironment.HOME_URL); 49 | } 50 | } -------------------------------------------------------------------------------- /src/test/java/com/pages/AuthenticationPage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.pages.base.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | /** 9 | * Test_Automation-automationpractice 10 | * 11 | * @author kamil.nowocin 12 | **/ 13 | 14 | public class AuthenticationPage extends BasePage { 15 | 16 | /** 17 | * CREATE AN ACCOUNT 18 | **/ 19 | //VIEW// 20 | @FindBy(how = How.XPATH, using = "//form[@id='create-account_form']") 21 | public WebElement createAccountPane; 22 | 23 | //BUTTONS & INPUTS & DROPDOWN// 24 | @FindBy(how = How.XPATH, using = "//input[@id='email_create']") 25 | public WebElement createAnAccountEmailInput; 26 | 27 | @FindBy(how = How.XPATH, using = "//button[@id='SubmitCreate']") 28 | public WebElement createAnAccountButton; 29 | 30 | //MESSAGES// 31 | @FindBy(how = How.XPATH, using = "//div[@id='create_account_error']") 32 | public WebElement createAnAccountError; 33 | 34 | /** 35 | * ALREADY REGISTERED 36 | **/ 37 | //VIEW// 38 | @FindBy(how = How.XPATH, using = "//form[@id='login_form']") 39 | public WebElement registeredPane; 40 | 41 | //MESSAGES// 42 | @FindBy(how = How.XPATH, using = "//div[@class='alert alert-danger']") 43 | public WebElement registeredLoginError; 44 | 45 | //BUTTONS & INPUTS & DROPDOWN// 46 | @FindBy(how = How.XPATH, using = "//input[@id='email']") 47 | public WebElement registeredEmailInput; 48 | 49 | @FindBy(how = How.XPATH, using = "//input[@id='passwd']") 50 | public WebElement registeredPasswordInput; 51 | 52 | @FindBy(how = How.XPATH, using = "//button[@id='SubmitLogin']") 53 | public WebElement registeredSignInButton; 54 | 55 | public AuthenticationPage() { 56 | super("/index.php"); 57 | } 58 | } -------------------------------------------------------------------------------- /src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | INFO 13 | 14 | 15 | %d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | testid 25 | unknown 26 | 27 | 28 | 29 | 30 | ALL 31 | ACCEPT 32 | 33 | ${LOG_PATH}/${testid}.log 34 | 35 | %d{HH:mm:ss} %-5level %logger{36} - %msg%n 36 | true 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/test/java/com/CucumberRunner.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import com.buildSettings.TestEnvironment; 4 | import io.cucumber.testng.*; 5 | import org.testng.annotations.AfterClass; 6 | import org.testng.annotations.BeforeClass; 7 | import org.testng.annotations.DataProvider; 8 | import org.testng.annotations.Test; 9 | 10 | /** 11 | * Test_Automation-automationpractice 12 | * 13 | * @author kamil.nowocin 14 | **/ 15 | 16 | @CucumberOptions( 17 | tags = "not @ignore", 18 | features = { 19 | "src/test/resources/features" 20 | }, 21 | glue = { 22 | "com.steps" 23 | }, 24 | plugin = { 25 | "pretty", "html:target/cucumber-report/single", 26 | "json:target/reports/cucumber.json", 27 | }, 28 | publish = true 29 | ) 30 | //This is experimental file and doesn't work well when using current settings. 31 | //If you would like to use CucumberRunner for running feature files, you have to edit build.gradle file. 32 | public class CucumberRunner extends AbstractTestNGCucumberTests { 33 | private TestNGCucumberRunner testNGCucumberRunner; 34 | 35 | private final TestEnvironment testEnvironment = new TestEnvironment(); 36 | 37 | @BeforeClass(alwaysRun = true) 38 | public void setUpClass() { 39 | testNGCucumberRunner = new TestNGCucumberRunner(this.getClass()); 40 | } 41 | 42 | @Test(groups = "Cucumber", description = "Runs Cucumber Scenarios", dataProvider = "scenarios") 43 | public void runScenario(PickleWrapper pickleWrapper, FeatureWrapper featureWrapper) { 44 | testNGCucumberRunner.runScenario(pickleWrapper.getPickle()); 45 | } 46 | 47 | @DataProvider 48 | public Object[][] scenarios() { 49 | if (testNGCucumberRunner == null) { 50 | return new Object[0][0]; 51 | } 52 | return testNGCucumberRunner.provideScenarios(); 53 | } 54 | 55 | @AfterClass(alwaysRun = true) 56 | public void tearDownClass() { 57 | if (testNGCucumberRunner == null) { 58 | return; 59 | } 60 | testNGCucumberRunner.finish(); 61 | testEnvironment.allureWriteProperties(); 62 | testEnvironment.allureWriteExecutors(); 63 | } 64 | } -------------------------------------------------------------------------------- /src/test/resources/features/Authentication.feature: -------------------------------------------------------------------------------- 1 | #/** 2 | #* Test_Automation-automationpractice 3 | #* 4 | #* @author kamil.nowocin 5 | #**/ 6 | 7 | @authentication 8 | Feature: As a user I would like to log in automationpractice.com 9 | #--------------------------------------------------------------------------------# 10 | # [UserStory] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-111 # 11 | #--------------------------------------------------------------------------------# 12 | 13 | Background: Navigate to Login page 14 | Given I open home page 15 | And I can see automationpractice.com website 16 | And I click on Sign in button 17 | 18 | #--------------------------------------------------------------------------------# 19 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0001 20 | @smoke @critical @regression 21 | Scenario Outline:[US-111]/[1] As a user I can log into automationpractice.com using registered email "" & password "" 22 | Given I can see login form 23 | When I enter login "" 24 | And I enter password "" 25 | And I click on Submit button 26 | Then I can see welcome message 27 | 28 | Examples: SCENARIO OUTLINE DATA 29 | | email | password | 30 | | thor.odinson@example.com | 12345 | 31 | 32 | #--------------------------------------------------------------------------------# 33 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0002 34 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0003 35 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0004 36 | @non-smoke @normal @regression 37 | Scenario Outline:[US-111]/[2] As a user I can't log into automationpractice.com using email "" & password "" 38 | Given I can see login form 39 | When I enter login "" 40 | And I enter password "" 41 | And I click on Submit button 42 | Then I can see warning message with include "" 43 | 44 | Examples: SCENARIO OUTLINE DATA 45 | | email | password | warning message | 46 | | thanos.ALars@example.com | 12345 | Authentication failed | 47 | | thor.odinson@example.com | | Password is required | 48 | | | 12345 | An email address required | -------------------------------------------------------------------------------- /src/test/java/com/pages/CustomerServicePage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.pages.base.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | /** 9 | * Test_Automation-automationpractice 10 | * 11 | * @author kamil.nowocin 12 | **/ 13 | 14 | public class CustomerServicePage extends BasePage { 15 | 16 | //VIEW// 17 | @FindBy(how = How.XPATH, using = "//h1[@class='page-heading bottom-indent']") 18 | public WebElement contactUsHeader; 19 | 20 | @FindBy(how = How.XPATH, using = "//form[@class='contact-form-box']") 21 | public WebElement contactUsPane; 22 | 23 | //MESSAGES// 24 | @FindBy(how = How.XPATH, using = "//div[@class='alert alert-danger']//li") 25 | public WebElement contactUsErrorMessage; 26 | 27 | @FindBy(how = How.XPATH, using = "//p[@class='alert alert-success']") 28 | public WebElement contactUsSuccessMessage; 29 | 30 | //BUTTONS & INPUTS & DROPDOWN// 31 | @FindBy(how = How.XPATH, using = "//div[@class='col-xs-12 col-md-3']//select[@id='id_contact']") 32 | public WebElement subjectHeadingDropdown; 33 | 34 | @FindBy(how = How.XPATH, using = "//div[@class='col-xs-12 col-md-3']//div[@class='form-group selector1']//span") 35 | public WebElement readSubjectHeading; 36 | 37 | @FindBy(how = How.XPATH, using = "//div[@class='col-xs-12 col-md-3']//input[@id='email']") 38 | public WebElement emailAddressInput; 39 | 40 | @FindBy(how = How.XPATH, using = "//div[@class='col-xs-12 col-md-3']//input[@id='id_order']") 41 | public WebElement orderReferenceInput; 42 | 43 | @FindBy(how = How.XPATH, using = "//div[@class='col-xs-12 col-md-3']//input[@type='file']") 44 | public WebElement attachFileInput; 45 | 46 | @FindBy(how = How.XPATH, using = "//div[@class='col-xs-12 col-md-3']//span[@class='action']") 47 | public WebElement chooseFileButton; 48 | 49 | @FindBy(how = How.XPATH, using = "//div[@class='col-xs-12 col-md-3']//span[@class='filename']") 50 | public WebElement readFileName; 51 | 52 | @FindBy(how = How.XPATH, using = "//div[@class='col-xs-12 col-md-9']//textarea[@class='form-control']") 53 | public WebElement messageTextArea; 54 | 55 | @FindBy(how = How.XPATH, using = "//div[@class='submit']//button") 56 | public WebElement sendButton; 57 | 58 | public CustomerServicePage() { 59 | super("/index.php"); 60 | } 61 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega -------------------------------------------------------------------------------- /src/test/java/com/steps/hooks/WEB_Hooks.java: -------------------------------------------------------------------------------- 1 | package com.steps.hooks; 2 | 3 | import com.DriverFactory; 4 | import com.buildListeners.TestNGListener; 5 | import com.buildSettings.ExcelEnvironment; 6 | import com.buildSettings.MessageBuilder; 7 | import com.buildSettings.TestCommons; 8 | import io.cucumber.java.After; 9 | import io.cucumber.java.Before; 10 | import io.cucumber.java.Scenario; 11 | import org.slf4j.MDC; 12 | import org.testng.ITestListener; 13 | import org.testng.ITestResult; 14 | import org.testng.annotations.AfterMethod; 15 | import org.testng.annotations.AfterSuite; 16 | import org.testng.annotations.BeforeMethod; 17 | import org.testng.annotations.BeforeTest; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * Test_Automation-automationpractice 23 | * 24 | * @author kamil.nowocin 25 | **/ 26 | 27 | public class WEB_Hooks extends DriverFactory implements ITestListener { 28 | 29 | private final TestCommons testCommons = new TestCommons(); 30 | private final TestNGListener testNGListener = new TestNGListener(); 31 | private final ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 32 | 33 | /** 34 | * For TestNG -> @Test annotation 35 | **/ 36 | @BeforeTest(alwaysRun = true, description = "Setting up Excel File") 37 | public void dataSetup() { 38 | excelEnvironment.setExcelSheet(ExcelEnvironment.TEST_DATA_EXCEL_SHEET_NAME); 39 | } 40 | 41 | @BeforeMethod(alwaysRun = true, description = "Setting up Test Class") 42 | public void beforeTest(ITestResult iTestResult) throws IOException { 43 | MDC.put("testid", MessageBuilder.getTestDescription(iTestResult)); 44 | startBrowser(); 45 | testCommons.networkThrottling(false); 46 | } 47 | 48 | @AfterMethod(alwaysRun = true, description = "Teardown Test Class") 49 | public void afterTest() { 50 | MDC.remove("testid"); 51 | getDriver().close(); 52 | } 53 | 54 | @AfterSuite(alwaysRun = true, description = "Teardown Test Suite") 55 | public void afterSuite() { 56 | destroyDriver(); 57 | } 58 | 59 | /** 60 | * For Cucumber -> Feature file 61 | **/ 62 | @Before 63 | public void beforeScenario(Scenario scenario) throws IOException { 64 | MDC.put("testid", scenario.getName().toUpperCase()); 65 | testNGListener.onScenarioStart(scenario); 66 | startBrowser(); 67 | testCommons.networkThrottling(false); 68 | } 69 | 70 | @After 71 | public void afterScenario(Scenario scenario) throws IOException { 72 | testNGListener.onScenarioFinish(scenario); 73 | MDC.remove("testid"); 74 | destroyDriver(); 75 | } 76 | } -------------------------------------------------------------------------------- /src/test/resources/features/Shopping-LoggedUser.feature: -------------------------------------------------------------------------------- 1 | #/** 2 | #* Test_Automation-automationpractice 3 | #* 4 | #* @author kamil.nowocin 5 | #**/ 6 | 7 | @shopping 8 | Feature: As a user I would like to buy new clothes from automationpractice.com - User is already successfully logged 9 | #--------------------------------------------------------------------------------# 10 | # [UserStory] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-666 # 11 | #--------------------------------------------------------------------------------# 12 | 13 | Background: Navigate to automationpractice.com website 14 | Given I open home page 15 | And I can see automationpractice.com website 16 | When I am logged as customer "thor.odinson@example.com" using "12345" password 17 | Then I can see welcome message 18 | 19 | #--------------------------------------------------------------------------------# 20 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0039 21 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0040 22 | @smoke @critical @regression 23 | Scenario Outline:[US-666]/[1] As a user I would like to buy new "" 24 | Given I am on MyAccount details page 25 | And I click on "Women" button from sub menu 26 | And I click on following product "" 27 | And I choose following details of my order 28 | | Quantity | Size | Colour | 29 | | | | | 30 | When I click on Add To Cart button 31 | And I can see modal where I am able to see detailed data about my purchase 32 | And I click on Proceed To Checkout button (from modal) 33 | And I can see Shopping-Cart "Your shopping cart" form with valid information 34 | And I click on Proceed To Checkout button (from shopping-cart) 35 | And I can see Shopping-Cart "Addresses" form with valid information 36 | And I write comment about my order 37 | And I click on Proceed To Checkout button (from shopping-cart) 38 | And I can see Shopping-Cart "Shipping" form with valid information 39 | And I choose shipping option "My carrier" 40 | And I click on Terms of Service checkbox 41 | And I click on Proceed To Checkout button (from shopping-cart) 42 | And I can see Shopping-Cart "Your payment method" form with valid information 43 | Then I choose payment method 44 | | Payment Method | 45 | | | 46 | And I click on I Confirm My Order button 47 | And I can see Shopping-Cart "Order confirmation" form with valid information 48 | 49 | Examples: SCENARIO OUTLINE DATA 50 | | dress name | quantity | size | colour | payment method | 51 | | Faded Short Sleeve T-shirts | 5 | M | Blue | Pay by check | 52 | | Blouse | 2 | S | Black | Pay by bank wire | -------------------------------------------------------------------------------- /src/test/java/com/steps/AuthenticationPageSteps.java: -------------------------------------------------------------------------------- 1 | package com.steps; 2 | 3 | import com.buildSettings.ContextInjection; 4 | import com.buildSettings.TestCommons; 5 | import com.buildSettings.TestEnvironment; 6 | import com.pages.AuthenticationPage; 7 | import io.cucumber.java.en.And; 8 | import io.cucumber.java.en.Given; 9 | import io.cucumber.java.en.Then; 10 | import io.qameta.allure.Step; 11 | import org.testng.Assert; 12 | 13 | /** 14 | * Test_Automation-automationpractice 15 | * 16 | * @author kamil.nowocin 17 | **/ 18 | 19 | public class AuthenticationPageSteps extends TestEnvironment { 20 | 21 | private final TestCommons testCommons = new TestCommons(); 22 | private final AuthenticationPage authenticationPage = new AuthenticationPage().get(); 23 | 24 | @Step("I can see login form") 25 | @Given("I can see login form") 26 | public void iCanSeeLoginForm() throws Throwable { 27 | Assert.assertTrue(testCommons.isElementVisible(authenticationPage.registeredPane), 28 | String.format(ContextInjection.VIEW_ERROR, "Login form")); 29 | } 30 | 31 | @Step("I enter login *{0}*") 32 | @And("I enter login {string}") 33 | public void iEnterLogin(String login) throws Throwable { 34 | //ACT// 35 | testCommons.customSendKeys(authenticationPage.registeredEmailInput, login); 36 | logger.info(String.format("User login: \"%S\"", login)); 37 | 38 | //ASSERT// 39 | Assert.assertEquals(authenticationPage.registeredEmailInput.getAttribute("value").toLowerCase(), 40 | login.toLowerCase(), ContextInjection.VALUE_ERROR); 41 | } 42 | 43 | @Step("I enter password *{0}*") 44 | @And("I enter password {string}") 45 | public void iEnterPassword(String password) throws Throwable { 46 | //ACT// 47 | testCommons.customSendKeys(authenticationPage.registeredPasswordInput, password); 48 | logger.info(String.format("User password: \"%S\"", password)); 49 | 50 | //ASSERT// 51 | Assert.assertEquals(authenticationPage.registeredPasswordInput.getAttribute("value").toLowerCase(), 52 | password.toLowerCase(), ContextInjection.VALUE_ERROR); 53 | } 54 | 55 | @Step("I click on Submit button") 56 | @And("I click on Submit button") 57 | public void iClickOnSubmitButton() throws Throwable { 58 | testCommons.customClick(authenticationPage.registeredSignInButton); 59 | } 60 | 61 | 62 | @Step("I can see warning message with include *{0}*") 63 | @Then("I can see warning message with include {string}") 64 | public void iCanSeeWarningMessageWithInclude(String warningMessage) throws Throwable { 65 | Assert.assertTrue(authenticationPage.registeredLoginError.getText().toLowerCase().contains(warningMessage.toLowerCase()), 66 | String.format(ContextInjection.MESSAGE_DIDNT_CONTAIN, warningMessage.toUpperCase())); 67 | } 68 | } -------------------------------------------------------------------------------- /src/test/java/com/steps/MainPageSteps.java: -------------------------------------------------------------------------------- 1 | package com.steps; 2 | 3 | import com.DriverFactory; 4 | import com.buildSettings.ContextInjection; 5 | import com.buildSettings.TestCommons; 6 | import com.buildSettings.TestEnvironment; 7 | import com.pages.MainPage; 8 | import io.cucumber.java.en.Given; 9 | import io.cucumber.java.en.When; 10 | import io.qameta.allure.Step; 11 | import org.testng.Assert; 12 | 13 | /** 14 | * Test_Automation-automationpractice 15 | * 16 | * @author kamil.nowocin 17 | **/ 18 | 19 | public class MainPageSteps extends TestEnvironment { 20 | 21 | private final MainPage mainPage = new MainPage().get(); 22 | private final AuthenticationPageSteps authenticationPageSteps = new AuthenticationPageSteps(); 23 | private final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 24 | 25 | @Step("I open home page") 26 | @Given("I open home page") 27 | public void iOpenHomePage() throws Throwable { 28 | //ARRANGE// 29 | final String expectedPageURL = "http://automationpractice.com/index.php"; 30 | 31 | //ACT// 32 | DriverFactory.getDriver().get(HOME_URL); 33 | 34 | //ASSERT// 35 | Assert.assertEquals(DriverFactory.getDriver().getCurrentUrl(), expectedPageURL, ContextInjection._21VOID); 36 | } 37 | 38 | @Step("I can see automationpractice.com website") 39 | @Given("I can see automationpractice.com website") 40 | public void iCanSeeAutomationpracticeComWebsite() throws Throwable { 41 | //ARRANGE// 42 | final boolean isPageReadyToExecuteTests; 43 | 44 | //ACT// 45 | isPageReadyToExecuteTests = TestCommons.isPageReady(); 46 | logger.info(String.format("Page ready: \"%S\"", isPageReadyToExecuteTests)); 47 | 48 | //ASSERT// 49 | Assert.assertTrue(isPageReadyToExecuteTests, ContextInjection.PAGE_ERROR); 50 | } 51 | 52 | @Step("I am logged as customer *{0}* using *{1}* password") 53 | @When("I am logged as customer {string} using {string} password") 54 | public void iAmLoggedAsCustomerUsingPassword(String email, String password) throws Throwable { 55 | //ARRANGE// 56 | final String defaultUserName = ContextInjection.DEFAULT_CUSTOMER_USER_NAME; 57 | 58 | //ACT// 59 | registrationPageSteps.iClickOnSignInButton(); 60 | authenticationPageSteps.iEnterLogin(email); 61 | authenticationPageSteps.iEnterPassword(password); 62 | authenticationPageSteps.iClickOnSubmitButton(); 63 | 64 | //ASSERT// 65 | Assert.assertEquals(mainPage.currentLoggedUserName.getText().toLowerCase(), defaultUserName.toLowerCase(), ContextInjection.VALUE_ERROR); 66 | } 67 | 68 | @Step("I am on MyAccount details page") 69 | @Given("I am on MyAccount details page") 70 | public void iAmOnMyAccountDetailsPage() throws Throwable { 71 | registrationPageSteps.iCanSeeWelcomeMessage(); 72 | } 73 | } -------------------------------------------------------------------------------- /src/test/java/com/buildSettings/ExcelEnvironment.java: -------------------------------------------------------------------------------- 1 | package com.buildSettings; 2 | 3 | import org.apache.poi.xssf.usermodel.XSSFCell; 4 | import org.apache.poi.xssf.usermodel.XSSFRow; 5 | import org.apache.poi.xssf.usermodel.XSSFSheet; 6 | import org.apache.poi.xssf.usermodel.XSSFWorkbook; 7 | 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.FileOutputStream; 11 | import java.io.IOException; 12 | 13 | /** 14 | * Test_Automation-automationpractice 15 | * 16 | * @author kamil.nowocin 17 | **/ 18 | 19 | public class ExcelEnvironment extends TestEnvironment { 20 | 21 | private static XSSFRow excelRow; 22 | public static int excelRowNumber; 23 | private static XSSFSheet excelSheet; 24 | private static XSSFWorkbook excelWorkBook; 25 | private static String testDataExcelPath = null; 26 | 27 | public static int CUCUMBER_RESULT_COUNTER_ROW = 1; 28 | public static final int EXCEL_TC_NAME_COLUMN = 0; 29 | public static final int EXCEL_TC_RESULT_COLUMN = 4; 30 | public static final String TEST_DATA_EXCEL_FILE_NAME = "testdata.xlsx"; 31 | public static final String TEST_DATA_EXCEL_SHEET_NAME = "automationData"; 32 | 33 | public void setExcelRowNumber(int rowNumber) { 34 | excelRowNumber = rowNumber; 35 | } 36 | 37 | public int getExcelRowNumber() { 38 | return excelRowNumber; 39 | } 40 | 41 | public void saveTestResultsXLSX(int whichRowNumber) { 42 | setExcelRowNumber(whichRowNumber); 43 | } 44 | 45 | public void setExcelSheet(String excelSheetName) { 46 | testDataExcelPath = getCurrentPath() 47 | + File.separator 48 | + "src" 49 | + File.separator 50 | + "test" 51 | + File.separator 52 | + "resources" 53 | + File.separator 54 | + "files" 55 | + File.separator; 56 | try { 57 | FileInputStream ExcelFile = new FileInputStream(testDataExcelPath + TEST_DATA_EXCEL_FILE_NAME); 58 | excelWorkBook = new XSSFWorkbook(ExcelFile); 59 | excelSheet = excelWorkBook.getSheet(excelSheetName); 60 | } catch (IOException e) { 61 | e.printStackTrace(); 62 | } 63 | } 64 | 65 | public XSSFRow getRowData(int rowNumber) { 66 | excelRow = excelSheet.getRow(rowNumber); 67 | return excelRow; 68 | } 69 | 70 | public void setCellData(int rowNumber, String stringValue, int columnNumber) { 71 | try { 72 | excelRow = excelSheet.getRow(rowNumber); 73 | XSSFCell excelCell = excelRow.getCell(columnNumber); 74 | excelCell.setCellValue(stringValue); 75 | FileOutputStream fileOut = new FileOutputStream(testDataExcelPath + TEST_DATA_EXCEL_FILE_NAME); 76 | excelWorkBook.write(fileOut); 77 | fileOut.flush(); 78 | fileOut.close(); 79 | } catch (IOException e) { 80 | e.printStackTrace(); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/test/resources/features/SearchBox.feature: -------------------------------------------------------------------------------- 1 | #/** 2 | #* Test_Automation-automationpractice 3 | #* 4 | #* @author kamil.nowocin 5 | #**/ 6 | 7 | @searchBox 8 | Feature: A a user I would like to see results of searching phrase 9 | #--------------------------------------------------------------------------------# 10 | # [UserStory] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-555 # 11 | #--------------------------------------------------------------------------------# 12 | 13 | Background: Navigate to automationpractice.com website 14 | When I open home page 15 | 16 | #--------------------------------------------------------------------------------# 17 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0031 18 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0032 19 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0033 20 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0034 21 | @non-smoke @critical @regression 22 | Scenario Outline:[US-555]/[1] As a user I would like to use search box and be able to see results of: "" 23 | Given I can see automationpractice.com website 24 | When I search for phrase "" 25 | And I click on search icon 26 | Then I can see numbers of results equals to "" 27 | And I can see that every results which have been found contains phrase "" 28 | 29 | Examples: SCENARIO OUTLINE DATA 30 | | search phrase | expected results | 31 | | T-shirts | 1 | 32 | | Blouse | 1 | 33 | | Printed Dress | 5 | 34 | | !@#$%^ | 0 | 35 | 36 | #--------------------------------------------------------------------------------# 37 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0035 38 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0036 39 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0037 40 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0038 41 | @non-smoke @critical @regression 42 | Scenario Outline:[US-555]/[2] As a user I would like to use search box and be able to see results sorted by: "" 43 | Given I can see automationpractice.com website 44 | When I search for phrase "" 45 | And I click on search icon 46 | And I can see numbers of results equals to "" 47 | And I can see that every results which have been found contains phrase "" 48 | Then I select from Dropdown Sort by "" 49 | And I can see that results are correctly sorted by "" 50 | 51 | Examples: SCENARIO OUTLINE DATA 52 | | search phrase | expected results | sort by | sorted by | 53 | | Printed Dress | 5 | Product Name: Z to A | Product Name: Z to A | 54 | | Printed Dress | 5 | Product Name: A to Z | Product Name: A to Z | 55 | | Printed Dress | 5 | Price: Highest first | Price: Highest first | 56 | | Printed Dress | 5 | Price: Lowest first | Price: Lowest first | -------------------------------------------------------------------------------- /src/test/java/com/buildSettings/MessageBuilder.java: -------------------------------------------------------------------------------- 1 | package com.buildSettings; 2 | 3 | import com.DriverFactory; 4 | import io.cucumber.java.Scenario; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.testng.ITestContext; 7 | import org.testng.ITestResult; 8 | 9 | /** 10 | * Test_Automation-automationpractice 11 | * 12 | * @author kamil.nowocin 13 | **/ 14 | 15 | public class MessageBuilder extends TestEnvironment { 16 | 17 | public static String getXmlSuiteName(ITestContext iTestContext) { 18 | return iTestContext.getCurrentXmlTest().getSuite().getName(); 19 | } 20 | 21 | public static String getXmlTestName(ITestContext iTestContext) { 22 | return iTestContext.getName(); 23 | } 24 | 25 | public static String getTestDescription(ITestResult iTestResult) { 26 | return iTestResult.getMethod().getDescription().toUpperCase(); 27 | } 28 | 29 | public void messageStartSuite(ITestContext iTestContext) { 30 | logger.info(StringUtils.repeat("#", 110)); 31 | logger.info(StringUtils.repeat("=", 31) + "STARTING TEST SUITE " + iTestContext.getStartDate() + StringUtils.repeat("=", 30)); 32 | logger.info(StringUtils.repeat("#", 110)); 33 | } 34 | 35 | public void messageEndSuite(ITestContext iTestContext) { 36 | logger.info(StringUtils.repeat("#", 110)); 37 | logger.info(StringUtils.repeat("=", 32) + "END OF TEST SUITE " + iTestContext.getEndDate() + StringUtils.repeat("=", 31)); 38 | logger.info(StringUtils.repeat("#", 110)); 39 | } 40 | 41 | public void messageStartTest(ITestResult iTestResult) { 42 | logger.info(StringUtils.repeat("=", 48) + " TEST STARTED " + StringUtils.repeat("=", 48)); 43 | logger.info(ANSI_BLUE + "TEST NAME: " + getTestDescription(iTestResult) + ANSI_RESET); 44 | logger.info(String.format("Chosen executor: \"%S\"", DriverFactory.getTestsExecutor())); 45 | } 46 | 47 | public void messageSuccessTest() { 48 | logger.info(StringUtils.repeat("=", 37) + " TEST FINISHED WITH " + ANSI_GREEN + "SUCCESS STATUS " + ANSI_RESET + StringUtils.repeat("=", 38)); 49 | } 50 | 51 | public void messageFailTest() { 52 | logger.info(StringUtils.repeat("=", 38) + " TEST FINISHED WITH " + ANSI_RED + "FAILED STATUS " + ANSI_RESET + StringUtils.repeat("=", 38)); 53 | } 54 | 55 | public void messageStartScenario(Scenario scenario) { 56 | logger.info(StringUtils.repeat("#", 110)); 57 | logger.info(StringUtils.repeat("=", 46) + " BEFORE SCENARIO " + StringUtils.repeat("=", 47)); 58 | logger.info(StringUtils.repeat("#", 110)); 59 | logger.info(ANSI_BLUE + "SCENARIO NAME: " + scenario.getName().toUpperCase() + ANSI_RESET); 60 | logger.info(String.format("Chosen executor: \"%S\"", DriverFactory.getTestsExecutor())); 61 | } 62 | 63 | public void messageFinishScenario(Scenario scenario) { 64 | String status = (scenario.isFailed() ? ANSI_RED + "FAILED STATUS " + ANSI_RESET : ANSI_GREEN + "SUCCESS STATUS " + ANSI_RESET); 65 | logger.info(StringUtils.repeat("#", 110)); 66 | logger.info(StringUtils.repeat("=", 36) + " SCENARIO FINISHED WITH " + status + StringUtils.repeat("=", 35)); 67 | logger.info(StringUtils.repeat("#", 110)); 68 | System.out.println(); 69 | } 70 | } -------------------------------------------------------------------------------- /src/test/java/com/pages/ProductDetailsPage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.pages.base.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | /** 9 | * Test_Automation-automationpractice 10 | * 11 | * @author kamil.nowocin 12 | **/ 13 | 14 | public class ProductDetailsPage extends BasePage { 15 | 16 | //VIEW// 17 | @FindBy(how = How.XPATH, using = "//span[@id='our_price_display']") 18 | public WebElement productPrice; 19 | 20 | @FindBy(how = How.XPATH, using = "//h1[@itemprop='name']") 21 | public WebElement productName; 22 | 23 | //POPUP// 24 | @FindBy(how = How.XPATH, using = "//div[@id='layer_cart']//div[@class='clearfix']") 25 | public WebElement popupPaneProductDetails; 26 | 27 | //POPUP LEFT SIDE// 28 | @FindBy(how = How.XPATH, using = "//div[@id='layer_cart']//div[@class='clearfix']//i[@class='icon-ok']//parent::h2") 29 | public WebElement popupPaneAddedSuccessfully; 30 | 31 | @FindBy(how = How.XPATH, using = "//span[@id='layer_cart_product_title']") 32 | public WebElement popupPaneCartProductName; 33 | 34 | @FindBy(how = How.XPATH, using = "//span[@id='layer_cart_product_quantity']") 35 | public WebElement popupPaneCartProductQuantity; 36 | 37 | @FindBy(how = How.XPATH, using = "//span[@id='layer_cart_product_price']") 38 | public WebElement popupPaneCartProductPrice; 39 | 40 | //POPUP RIGHT SIDE// 41 | @FindBy(how = How.XPATH, using = "//span[@class='ajax_block_products_total']") 42 | public WebElement popupPaneCartTotalProductsPrice; 43 | 44 | @FindBy(how = How.XPATH, using = "//span[@class='ajax_cart_shipping_cost']") 45 | public WebElement popupPaneCartTotalShippingPrice; 46 | 47 | @FindBy(how = How.XPATH, using = "//span[@class='ajax_block_cart_total']") 48 | public WebElement popupPaneCartTotalPrice; 49 | 50 | //POPUP BUTTONS// 51 | @FindBy(how = How.XPATH, using = "//span[@class='continue btn btn-default button exclusive-medium']//span") 52 | public WebElement continueShoppingButton; 53 | 54 | @FindBy(how = How.XPATH, using = "//a[@class='btn btn-default button button-medium']") 55 | public WebElement proceedToCheckoutButton; 56 | 57 | //BUTTONS & INPUTS & DROPDOWN// 58 | @FindBy(how = How.XPATH, using = "//input[@id='quantity_wanted']") 59 | public WebElement quantityInput; 60 | 61 | @FindBy(how = How.XPATH, using = "//div[@id='uniform-group_1']//select") 62 | public WebElement sizeDropdown; 63 | 64 | @FindBy(how = How.XPATH, using = "//div[@id='uniform-group_1']//span") 65 | public WebElement readSizeDropdown; 66 | 67 | @FindBy(how = How.XPATH, using = "//a[@title='Blue']") 68 | public WebElement blueColorButton; 69 | 70 | @FindBy(how = How.XPATH, using = "//a[@title='Orange']") 71 | public WebElement orangeColorButton; 72 | 73 | @FindBy(how = How.XPATH, using = "//a[@title='White']") 74 | public WebElement whiteColorButton; 75 | 76 | @FindBy(how = How.XPATH, using = "//a[@title='Black']") 77 | public WebElement blackColorButton; 78 | 79 | @FindBy(how = How.XPATH, using = "//a[@title='Beige']") 80 | public WebElement beigeColorButton; 81 | 82 | @FindBy(how = How.XPATH, using = "//a[@title='Pink']") 83 | public WebElement pinkColorButton; 84 | 85 | @FindBy(how = How.XPATH, using = "//a[@title='Green']") 86 | public WebElement greenColorButton; 87 | 88 | @FindBy(how = How.XPATH, using = "//a[@title='Yellow']") 89 | public WebElement yellowColorButton; 90 | 91 | @FindBy(how = How.XPATH, using = "//a[@class='color_pick selected']") 92 | public WebElement readChosenColor; 93 | 94 | @FindBy(how = How.XPATH, using = "//p[@id='add_to_cart']//span[text()='Add to cart']") 95 | public WebElement addToCartButton; 96 | 97 | public ProductDetailsPage() { 98 | super("/index.php"); 99 | } 100 | } -------------------------------------------------------------------------------- /src/test/java/com/buildSettings/ContextInjection.java: -------------------------------------------------------------------------------- 1 | package com.buildSettings; 2 | 3 | import io.cucumber.guice.ScenarioScoped; 4 | 5 | /** 6 | * Test_Automation-automationpractice 7 | * 8 | * @author kamil.nowocin 9 | **/ 10 | 11 | @ScenarioScoped 12 | public class ContextInjection { 13 | 14 | /** 15 | * DATA 16 | **/ 17 | //TEST CASE RESULTS// 18 | public static int passedTestsAmount; 19 | public static int failedTestsAmount; 20 | 21 | //GENERAL DATA// 22 | public String paymentType; 23 | public String generatedEmail; 24 | 25 | //PRODUCT DATA// 26 | public String productSize; 27 | public String productColor; 28 | public double productQuantity; 29 | public double productUnitPrice; 30 | 31 | //PRODUCT POPUP DATA// 32 | public String cartProductName; 33 | public double cartProductPrice; 34 | public double cartTotalProductsPrice; 35 | public double cartTotalPrice; 36 | 37 | //ORDER DATA// 38 | public double totalOrderPriceWithoutTax; 39 | public double totalOrderTax; 40 | public double totalOrderPriceWithTax; 41 | 42 | /** 43 | * DEFAULT DATA 44 | **/ 45 | //CUSTOMER DATA// 46 | public static final String DEFAULT_REGISTERED_EMAIL_ADDRESS = 47 | "asfsafas@wp.pl"; 48 | public static final String DEFAULT_CUSTOMER_USER_NAME = 49 | "Thor Odinson"; 50 | public static final String DEFAULT_CUSTOMER_FIRST_LAST_NAME = 51 | "Thor Odinson"; 52 | public static final String DEFAULT_CUSTOMER_COMPANY_NAME = 53 | "Avengers"; 54 | public static final String DEFAULT_CUSTOMER_ADDRESS = 55 | "Asgard"; 56 | public static final String DEFAULT_CUSTOMER_COUNTRY = 57 | "United States"; 58 | public static final String DEFAULT_CUSTOMER_MOBILE_PHONE = 59 | "600500400"; 60 | 61 | //NAVIGATION MENU LABELS// 62 | public static final String LABEL_YOUR_SHOPPING_CART = 63 | "Your shopping cart"; 64 | public static final String LABEL_ADDRESSES = 65 | "Addresses"; 66 | public static final String LABEL_SHIPPING = 67 | "Shipping"; 68 | public static final String LABEL_YOUR_PAYMENT_METHOD = 69 | "Your payment method"; 70 | public static final String LABEL_ORDER_CONFIRMATION = 71 | "Order confirmation"; 72 | 73 | //ORDER DATA// 74 | public static final double SHIPPING_PRICE = 2.00; 75 | public static final double TAX_VALUE = 0.04; //DIFFERENT STATES IN UNITED STATES HAVE DIFFERENT TAX VALUE 76 | 77 | //EXPECTED HEADERS// 78 | public static final String WELCOME_MESSAGE = 79 | "Welcome to your account. Here you can manage all of your personal information and orders."; 80 | 81 | //ASSERTION MESSAGES// 82 | public static final String PAGE_URL_DIDNT_CONTAIN = 83 | "Following page URL didn't contain expected URL %s.com!"; 84 | public static final String MESSAGE_DIDNT_CONTAIN = 85 | "Warning message didn't contain \"%S\"!"; 86 | public static final String PAGE_ERROR = 87 | "Page wasn't ready to execute tests!"; 88 | public static final String RESULTS_ERROR = 89 | "Number of results which have been found didn't match expected number of results! \n Found: %S \n Expected: %S"; 90 | public static final String SEARCH_ERROR = 91 | "Names of results which have been found didn't match expected names! "; 92 | public static final String SORTING_ERROR = 93 | "Results which have been found didn't match expected sorting result %S"; 94 | public static final String VIEW_ERROR = 95 | "Element \"%S\" wasn't displayed!"; 96 | public static final String INPUT_ERROR = 97 | "Invalid input type! \"%S\" is not supported!"; 98 | public static final String VALUE_ERROR = 99 | "Value which have been found didn't match expected value!"; 100 | public static final String _21VOID = 101 | "Ups, something went really bad! Even Michael Scofield couldn't have predicted that error! :)"; 102 | } -------------------------------------------------------------------------------- /src/test/java/com/pages/RegistrationPage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.pages.base.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | /** 9 | * Test_Automation-automationpractice 10 | * 11 | * @author kamil.nowocin 12 | **/ 13 | 14 | public class RegistrationPage extends BasePage { 15 | 16 | //VIEW// 17 | @FindBy(how = How.XPATH, using = "//form[@id='account-creation_form']") 18 | public WebElement accountCreationPane; 19 | 20 | //MESSAGES// 21 | @FindBy(how = How.XPATH, using = "//div[@class='alert alert-danger']") 22 | public WebElement registerError; 23 | 24 | //BUTTONS & INPUTS & DROPDOWN// 25 | @FindBy(how = How.XPATH, using = "//input[@id='id_gender1']") 26 | public WebElement mrButton; 27 | 28 | @FindBy(how = How.XPATH, using = "//input[@id='id_gender2']") 29 | public WebElement mrsButton; 30 | 31 | @FindBy(how = How.XPATH, using = "//input[@id='customer_firstname']") 32 | public WebElement firstNameInput; 33 | 34 | @FindBy(how = How.XPATH, using = "//input[@id='customer_lastname']") 35 | public WebElement lastNameInput; 36 | 37 | @FindBy(how = How.XPATH, using = "//input[@id='email']") 38 | public WebElement emailInput; 39 | 40 | @FindBy(how = How.XPATH, using = "//input[@id='passwd']") 41 | public WebElement passwordInput; 42 | 43 | @FindBy(how = How.XPATH, using = "//select[@id='days']") 44 | public WebElement dayOfBirth; 45 | 46 | @FindBy(how = How.XPATH, using = "//div[@id='uniform-days']//span") 47 | public WebElement readDayOfBirth; 48 | 49 | @FindBy(how = How.XPATH, using = "//select[@id='months']") 50 | public WebElement monthOfBirth; 51 | 52 | @FindBy(how = How.XPATH, using = "//div[@id='uniform-months']//span") 53 | public WebElement readMonthOfBirth; 54 | 55 | @FindBy(how = How.XPATH, using = "//select[@id='years']") 56 | public WebElement yearOfBirth; 57 | 58 | @FindBy(how = How.XPATH, using = "//div[@id='uniform-years']//span") 59 | public WebElement readYearOfBirth; 60 | 61 | @FindBy(how = How.XPATH, using = "//input[@id='newsletter']") 62 | public WebElement newsletterCheckbox; 63 | 64 | @FindBy(how = How.XPATH, using = "//input[@id='optin']") 65 | public WebElement specialOffersCheckbox; 66 | 67 | @FindBy(how = How.XPATH, using = "//input[@id='firstname']") 68 | public WebElement assertFirstNameInput; 69 | 70 | @FindBy(how = How.XPATH, using = "//input[@id='lastname']") 71 | public WebElement assertLastNameInput; 72 | 73 | @FindBy(how = How.XPATH, using = "//input[@id='company']") 74 | public WebElement companyInput; 75 | 76 | @FindBy(how = How.XPATH, using = "//input[@id='address1']") 77 | public WebElement addressInput; 78 | 79 | @FindBy(how = How.XPATH, using = "//input[@id='address2']") 80 | public WebElement addressSecondInput; 81 | 82 | @FindBy(how = How.XPATH, using = "//input[@id='city']") 83 | public WebElement cityInput; 84 | 85 | @FindBy(how = How.XPATH, using = "//select[@id='id_state']") 86 | public WebElement stateDropDown; 87 | 88 | @FindBy(how = How.XPATH, using = "//p[@class='required id_state select form-group']//span") 89 | public WebElement readStateDropdown; 90 | 91 | @FindBy(how = How.XPATH, using = "//input[@id='postcode']") 92 | public WebElement postalCodeInput; 93 | 94 | @FindBy(how = How.XPATH, using = "//select[@id='id_country']") 95 | public WebElement countryDropDown; 96 | 97 | @FindBy(how = How.XPATH, using = "//div[@id='uniform-id_country']//span") 98 | public WebElement readCountryDropdown; 99 | 100 | @FindBy(how = How.XPATH, using = "//textarea[@id='other']") 101 | public WebElement additionalInformationBox; 102 | 103 | @FindBy(how = How.XPATH, using = "//input[@id='phone']") 104 | public WebElement homePhoneInput; 105 | 106 | @FindBy(how = How.XPATH, using = "//input[@id='phone_mobile']") 107 | public WebElement mobilePhoneInput; 108 | 109 | @FindBy(how = How.XPATH, using = "//input[@id='alias']") 110 | public WebElement addressAliasInput; 111 | 112 | @FindBy(how = How.XPATH, using = "//button[@id='submitAccount']") 113 | public WebElement registerButton; 114 | 115 | public RegistrationPage() { 116 | super("/index.php"); 117 | } 118 | } -------------------------------------------------------------------------------- /src/test/java/com/steps/SocialMediaPageSteps.java: -------------------------------------------------------------------------------- 1 | package com.steps; 2 | 3 | import com.DriverFactory; 4 | import com.buildSettings.ContextInjection; 5 | import com.buildSettings.TestCommons; 6 | import com.buildSettings.TestEnvironment; 7 | import com.pages.SocialMediaPage; 8 | import io.cucumber.java.en.And; 9 | import io.cucumber.java.en.Then; 10 | import io.cucumber.java.en.When; 11 | import io.qameta.allure.Step; 12 | import org.testng.Assert; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | /** 18 | * Test_Automation-automationpractice 19 | * 20 | * @author kamil.nowocin 21 | **/ 22 | 23 | public class SocialMediaPageSteps extends TestEnvironment { 24 | 25 | private final TestCommons testCommons = new TestCommons(); 26 | private final SocialMediaPage socialMediaPage = new SocialMediaPage().get(); 27 | 28 | @Step("I scroll the website until I can see *{0}* logo") 29 | @When("I scroll the website until I can see {string} logo") 30 | public void iScrollTheWebsiteUntilICanSeeLogo(String logoName) throws Throwable { 31 | //ACT// 32 | switch (logoName.toLowerCase()) { 33 | case "facebook": 34 | testCommons.scrollWebsiteToElement(socialMediaPage.facebookButton); 35 | Assert.assertTrue(testCommons.isElementVisible(socialMediaPage.facebookButton), 36 | String.format(ContextInjection.VIEW_ERROR, logoName.toUpperCase())); 37 | break; 38 | case "twitter": 39 | testCommons.scrollWebsiteToElement(socialMediaPage.twitterButton); 40 | Assert.assertTrue(testCommons.isElementVisible(socialMediaPage.twitterButton), 41 | String.format(ContextInjection.VIEW_ERROR, logoName.toUpperCase())); 42 | break; 43 | case "youtube": 44 | testCommons.scrollWebsiteToElement(socialMediaPage.youtubeButton); 45 | Assert.assertTrue(testCommons.isElementVisible(socialMediaPage.youtubeButton), 46 | String.format(ContextInjection.VIEW_ERROR, logoName.toUpperCase())); 47 | break; 48 | case "google": 49 | testCommons.scrollWebsiteToElement(socialMediaPage.googleButton); 50 | Assert.assertTrue(testCommons.isElementVisible(socialMediaPage.googleButton), 51 | String.format(ContextInjection.VIEW_ERROR, logoName.toUpperCase())); 52 | break; 53 | default: 54 | throw new IllegalStateException(String.format(ContextInjection.INPUT_ERROR, logoName.toUpperCase())); 55 | } 56 | } 57 | 58 | @Step("I click on *{0}* logo button") 59 | @And("I click on {string} logo button") 60 | public void iClickOnLogoButton(String logoName) throws Throwable { 61 | //ACT// 62 | switch (logoName.toLowerCase()) { 63 | case "facebook": 64 | testCommons.customClick(socialMediaPage.facebookButton); 65 | break; 66 | case "twitter": 67 | testCommons.customClick(socialMediaPage.twitterButton); 68 | break; 69 | case "youtube": 70 | testCommons.customClick(socialMediaPage.youtubeButton); 71 | break; 72 | case "google": 73 | testCommons.customClick(socialMediaPage.googleButton); 74 | break; 75 | default: 76 | throw new IllegalStateException(String.format(ContextInjection.INPUT_ERROR, logoName.toUpperCase())); 77 | } 78 | logger.info(String.format("Chosen social media platform: \"%S\"", logoName)); 79 | } 80 | 81 | @Step("I am redirected to Selenium *{0}* profile") 82 | @Then("I am redirected to Selenium {string} profile") 83 | public void iAmRedirectedToSeleniumProfile(String logoName) throws Throwable { 84 | //ARRANGE// 85 | List browserTabs = new ArrayList<>(DriverFactory.getDriver().getWindowHandles()); 86 | 87 | //ACT// 88 | DriverFactory.getDriver().switchTo().window(browserTabs.get(1)); 89 | logger.info(String.format("URL was: \"%S\" URL expected: \"%S\"", DriverFactory.getDriver().getCurrentUrl(), logoName + ".com")); 90 | 91 | //ASSERT// 92 | Assert.assertTrue(DriverFactory.getDriver().getCurrentUrl().contains(logoName.toLowerCase() + ".com"), 93 | String.format(ContextInjection.PAGE_URL_DIDNT_CONTAIN, logoName.toUpperCase())); 94 | } 95 | } -------------------------------------------------------------------------------- /src/test/java/com/buildListeners/TestNGListener.java: -------------------------------------------------------------------------------- 1 | package com.buildListeners; 2 | 3 | import com.DriverFactory; 4 | import com.buildLogger.SlackLogger; 5 | import com.buildSettings.ContextInjection; 6 | import com.buildSettings.ExcelEnvironment; 7 | import com.buildSettings.MessageBuilder; 8 | import com.buildSettings.TestEnvironment; 9 | import io.cucumber.java.Scenario; 10 | import org.testng.ITestContext; 11 | import org.testng.ITestListener; 12 | import org.testng.ITestResult; 13 | 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | /** 19 | * Test_Automation-automationpractice 20 | * 21 | * @author kamil.nowocin 22 | **/ 23 | 24 | public class TestNGListener extends ExcelEnvironment implements ITestListener { 25 | 26 | public static List passedTests = new ArrayList<>(); 27 | public static List failedTests = new ArrayList<>(); 28 | 29 | private final SlackLogger slackLogger = new SlackLogger(); 30 | private final MessageBuilder messageBuilder = new MessageBuilder(); 31 | private final TestEnvironment testEnvironment = new TestEnvironment(); 32 | private final ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 33 | 34 | /** 35 | * For TestNG tests 36 | */ 37 | @Override 38 | public synchronized void onStart(ITestContext iTestContext) { 39 | deleteOldLogs(); 40 | messageBuilder.messageStartSuite(iTestContext); 41 | } 42 | 43 | @Override 44 | public synchronized void onFinish(ITestContext iTestContext) { 45 | messageBuilder.messageEndSuite(iTestContext); 46 | testEnvironment.allureWriteExecutors(); 47 | testEnvironment.allureWriteProperties(); 48 | ContextInjection.passedTestsAmount = passedTests.size(); 49 | ContextInjection.failedTestsAmount = failedTests.size(); 50 | slackLogger.sendTestExecutionStatusToSlack(iTestContext); 51 | suiteResultsCleaner(); 52 | } 53 | 54 | @Override 55 | public synchronized void onTestStart(ITestResult iTestResult) { 56 | messageBuilder.messageStartTest(iTestResult); 57 | } 58 | 59 | @Override 60 | public synchronized void onTestSuccess(ITestResult iTestResult) { 61 | messageBuilder.messageSuccessTest(); 62 | excelEnvironment.setCellData(excelEnvironment.getExcelRowNumber(), "PASSED", EXCEL_TC_RESULT_COLUMN); 63 | excelEnvironment.setCellData(excelEnvironment.getExcelRowNumber(), MessageBuilder.getTestDescription(iTestResult), EXCEL_TC_NAME_COLUMN); 64 | passedTests.add(MessageBuilder.getTestDescription(iTestResult)); 65 | } 66 | 67 | @Override 68 | public synchronized void onTestFailure(ITestResult iTestResult) { 69 | messageBuilder.messageFailTest(); 70 | excelEnvironment.setCellData(excelEnvironment.getExcelRowNumber(), "FAILED", EXCEL_TC_RESULT_COLUMN); 71 | excelEnvironment.setCellData(excelEnvironment.getExcelRowNumber(), MessageBuilder.getTestDescription(iTestResult), EXCEL_TC_NAME_COLUMN); 72 | failedTests.add(MessageBuilder.getTestDescription(iTestResult)); 73 | logger.error(String.valueOf(iTestResult.getThrowable())); 74 | if (DriverFactory.getDriver() != null) { 75 | allureSaveScreenshotPNG(); 76 | } 77 | allureSaveTextLog(iTestResult); 78 | } 79 | 80 | /** 81 | * For Cucumber tests 82 | **/ 83 | public void onScenarioStart(Scenario scenario) { 84 | messageBuilder.messageStartScenario(scenario); 85 | } 86 | 87 | public void onScenarioFinish(Scenario scenario) throws IOException { 88 | messageBuilder.messageFinishScenario(scenario); 89 | setExcelCucumberTestsResult(scenario); 90 | } 91 | 92 | private void setExcelCucumberTestsResult(Scenario scenario) throws IOException { 93 | excelEnvironment.setExcelSheet(TEST_DATA_EXCEL_SHEET_NAME); 94 | excelEnvironment.saveTestResultsXLSX(CUCUMBER_RESULT_COUNTER_ROW); 95 | if (scenario.isFailed()) { 96 | excelEnvironment.setCellData(excelEnvironment.getExcelRowNumber(), "FAILED", EXCEL_TC_RESULT_COLUMN); 97 | localSaveScreenshotPNG(scenario); 98 | allureSaveScreenshotPNG(); 99 | allureSaveTextLogCucumber(scenario); 100 | } else { 101 | excelEnvironment.setCellData(excelEnvironment.getExcelRowNumber(), "PASSED", EXCEL_TC_RESULT_COLUMN); 102 | } 103 | excelEnvironment.setCellData(excelEnvironment.getExcelRowNumber(), scenario.getName(), EXCEL_TC_NAME_COLUMN); 104 | CUCUMBER_RESULT_COUNTER_ROW++; 105 | } 106 | } -------------------------------------------------------------------------------- /src/test/java/com/pages/ShoppingCartSummaryPage.java: -------------------------------------------------------------------------------- 1 | package com.pages; 2 | 3 | import com.pages.base.BasePage; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.How; 7 | 8 | /** 9 | * Test_Automation-automationpractice 10 | * 11 | * @author kamil.nowocin 12 | **/ 13 | 14 | public class ShoppingCartSummaryPage extends BasePage { 15 | 16 | /** 17 | * GLOBAL 18 | **/ 19 | //VIEW// 20 | @FindBy(how = How.XPATH, using = "//span[@class='navigation_page']") 21 | public WebElement navigationTopLabelHeader; 22 | 23 | //BUTTONS & INPUTS & DROPDOWN// 24 | @FindBy(how = How.XPATH, using = "(//span[contains(text(),'Proceed to checkout')]//i[@class='icon-chevron-right right'])[2]") 25 | public WebElement proceedToCheckoutButton; 26 | 27 | @FindBy(how = How.XPATH, using = "//button[@class='button btn btn-default button-medium']//span") 28 | public WebElement iConfirmMyOrderButton; 29 | 30 | /** 31 | * YOUR SHOPPING CART 32 | **/ 33 | //VIEW// 34 | @FindBy(how = How.XPATH, using = "//td[@class='cart_description']//p[@class='product-name']//a") 35 | public WebElement productName; 36 | 37 | @FindBy(how = How.XPATH, using = "//span[@class='price']//span[@class='price']") 38 | public WebElement productUnitPrice; 39 | 40 | @FindBy(how = How.XPATH, using = "//input[@class='cart_quantity_input form-control grey']") 41 | public WebElement productQuantity; 42 | 43 | @FindBy(how = How.XPATH, using = "//td[@class='cart_total']//span[@class='price']") 44 | public WebElement productTotalPrice; 45 | 46 | @FindBy(how = How.XPATH, using = "//td[@id='total_product']") 47 | public WebElement totalProductsPrice; 48 | 49 | @FindBy(how = How.XPATH, using = "//td[@id='total_shipping']") 50 | public WebElement totalOrderShipping; 51 | 52 | @FindBy(how = How.XPATH, using = "//td[@id='total_price_without_tax']") 53 | public WebElement totalOrderPriceWithoutTax; 54 | 55 | @FindBy(how = How.XPATH, using = "//td[@id='total_tax']") 56 | public WebElement totalOrderTax; 57 | 58 | @FindBy(how = How.XPATH, using = "//span[@id='total_price']") 59 | public WebElement totalOrderPriceWithTax; 60 | 61 | /** 62 | * ADDRESSES 63 | **/ 64 | //VIEW// 65 | @FindBy(how = How.XPATH, using = "//ul[@id='address_delivery']//li[@class='address_firstname address_lastname']") 66 | public WebElement readCustomerFirstLastName; 67 | 68 | @FindBy(how = How.XPATH, using = "//ul[@id='address_delivery']//li[@class='address_company']") 69 | public WebElement readCustomerCompanyName; 70 | 71 | @FindBy(how = How.XPATH, using = "//ul[@id='address_delivery']//li[@class='address_address1 address_address2']") 72 | public WebElement readCustomerAddress; 73 | 74 | @FindBy(how = How.XPATH, using = "//ul[@id='address_delivery']//li[@class='address_city address_state_name address_postcode']") 75 | public WebElement readCustomerCity; 76 | 77 | @FindBy(how = How.XPATH, using = "//ul[@id='address_delivery']//li[@class='address_country_name']") 78 | public WebElement readCustomerCountry; 79 | 80 | @FindBy(how = How.XPATH, using = "//ul[@id='address_delivery']//li[@class='address_phone_mobile']") 81 | public WebElement readCustomerMobilePhone; 82 | 83 | //BUTTONS & INPUTS & DROPDOWN// 84 | @FindBy(how = How.XPATH, using = "//textarea[@name='message']") 85 | public WebElement orderCommentInput; 86 | 87 | /** 88 | * SHIPPING 89 | **/ 90 | //VIEW// 91 | @FindBy(how = How.XPATH, using = "//td[@class='delivery_option_radio']//input") 92 | public WebElement myCarrierRadioButton; 93 | 94 | @FindBy(how = How.XPATH, using = "//div[@class='delivery_option_price']") 95 | public WebElement readMyCarrierPrice; 96 | 97 | //BUTTONS & INPUTS & DROPDOWN// 98 | @FindBy(how = How.XPATH, using = "//input[@name='cgv']") 99 | public WebElement tosCheckbox; 100 | 101 | /** 102 | * YOUR PAYMENT METHOD 103 | **/ 104 | //VIEW// 105 | @FindBy(how = How.XPATH, using = "//a[@class='bankwire']") 106 | public WebElement bankWirePaymentBox; 107 | 108 | @FindBy(how = How.XPATH, using = "//a[@class='cheque']") 109 | public WebElement chequePaymentBox; 110 | 111 | /** 112 | * Order confirmation 113 | **/ 114 | //MESSAGES// 115 | @FindBy(how = How.XPATH, using = "//p[@class='alert alert-success']") 116 | public WebElement paymentByCheckSuccessful; 117 | 118 | @FindBy(how = How.XPATH, using = "//p[@class='cheque-indent']//strong") 119 | public WebElement paymentByBankWireSuccessful; 120 | 121 | public ShoppingCartSummaryPage() { 122 | super("/index.php"); 123 | } 124 | } -------------------------------------------------------------------------------- /src/test/java/tests/WebAPP/SocialMedia_Tests.java: -------------------------------------------------------------------------------- 1 | package tests.WebAPP; 2 | 3 | import com.buildListeners.TestNGListener; 4 | import com.buildSettings.ExcelEnvironment; 5 | import com.steps.MainPageSteps; 6 | import com.steps.SocialMediaPageSteps; 7 | import com.steps.hooks.WEB_Hooks; 8 | import io.qameta.allure.*; 9 | import org.testng.annotations.Listeners; 10 | import org.testng.annotations.Test; 11 | 12 | /** 13 | * Test_Automation-automationpractice 14 | * 15 | * @author kamil.nowocin 16 | **/ 17 | 18 | @Epic("Web App Tests") 19 | @Feature("SOCIAL MEDIA TESTS") 20 | @Listeners({TestNGListener.class}) 21 | public class SocialMedia_Tests extends WEB_Hooks { 22 | 23 | @Issue("TAP-0041") 24 | @TmsLink("STORY-777") 25 | @Story("POSITIVE FLOW") 26 | @Owner("Kamil Nowocin") 27 | @Severity(SeverityLevel.MINOR) 28 | @Description("[US-777]/[1] I click on social media \"Facebook\" logo") 29 | @Test(description = "[US-777]/[1] I click on social media \"Facebook\" logo", 30 | priority = 0) 31 | public void test_1() throws Throwable { 32 | //ARRANGE// 33 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 34 | final MainPageSteps mainPageSteps = new MainPageSteps(); 35 | final SocialMediaPageSteps mediaPageSteps = new SocialMediaPageSteps(); 36 | 37 | excelEnvironment.saveTestResultsXLSX(41); 38 | 39 | //ACT// 40 | mainPageSteps.iOpenHomePage(); 41 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 42 | mediaPageSteps.iScrollTheWebsiteUntilICanSeeLogo("facebook"); 43 | mediaPageSteps.iClickOnLogoButton("facebook"); 44 | 45 | //ASSERT// 46 | mediaPageSteps.iAmRedirectedToSeleniumProfile("facebook"); 47 | } 48 | 49 | @Issue("TAP-0042") 50 | @TmsLink("STORY-777") 51 | @Story("POSITIVE FLOW") 52 | @Owner("Kamil Nowocin") 53 | @Severity(SeverityLevel.MINOR) 54 | @Test(description = "[US-777]/[2] I click on social media \"Twitter\" logo", 55 | priority = 0) 56 | @Description("[US-777]/[2] I click on social media \"Twitter\" logo") 57 | public void test_2() throws Throwable { 58 | //ARRANGE// 59 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 60 | final MainPageSteps mainPageSteps = new MainPageSteps(); 61 | final SocialMediaPageSteps mediaPageSteps = new SocialMediaPageSteps(); 62 | 63 | excelEnvironment.saveTestResultsXLSX(42); 64 | 65 | //ACT// 66 | mainPageSteps.iOpenHomePage(); 67 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 68 | mediaPageSteps.iScrollTheWebsiteUntilICanSeeLogo("twitter"); 69 | mediaPageSteps.iClickOnLogoButton("twitter"); 70 | 71 | //ASSERT// 72 | mediaPageSteps.iAmRedirectedToSeleniumProfile("twitter"); 73 | } 74 | 75 | @Issue("TAP-0043") 76 | @TmsLink("STORY-777") 77 | @Story("POSITIVE FLOW") 78 | @Owner("Kamil Nowocin") 79 | @Severity(SeverityLevel.MINOR) 80 | @Test(description = "[US-777]/[3] I click on social media \"YouTube\" logo", 81 | priority = 0) 82 | @Description("[US-777]/[3] I click on social media \"YouTube\" logo") 83 | public void test_3() throws Throwable { 84 | //ARRANGE// 85 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 86 | final MainPageSteps mainPageSteps = new MainPageSteps(); 87 | final SocialMediaPageSteps mediaPageSteps = new SocialMediaPageSteps(); 88 | 89 | excelEnvironment.saveTestResultsXLSX(43); 90 | 91 | //ACT// 92 | mainPageSteps.iOpenHomePage(); 93 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 94 | mediaPageSteps.iScrollTheWebsiteUntilICanSeeLogo("youtube"); 95 | mediaPageSteps.iClickOnLogoButton("youtube"); 96 | 97 | //ASSERT// 98 | mediaPageSteps.iAmRedirectedToSeleniumProfile("youtube"); 99 | } 100 | 101 | @Issue("TAP-0044") 102 | @TmsLink("STORY-777") 103 | @Story("POSITIVE FLOW") 104 | @Owner("Kamil Nowocin") 105 | @Severity(SeverityLevel.MINOR) 106 | @Test(description = "[US-777]/[4] I click on social media \"Google+\" logo", 107 | priority = 0) 108 | @Description("[US-777]/[4] I click on social media \"Google+\" logo") 109 | public void test_4() throws Throwable { 110 | //ARRANGE// 111 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 112 | final MainPageSteps mainPageSteps = new MainPageSteps(); 113 | final SocialMediaPageSteps mediaPageSteps = new SocialMediaPageSteps(); 114 | 115 | excelEnvironment.saveTestResultsXLSX(44); 116 | 117 | //ACT// 118 | mainPageSteps.iOpenHomePage(); 119 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 120 | mediaPageSteps.iScrollTheWebsiteUntilICanSeeLogo("google"); 121 | mediaPageSteps.iClickOnLogoButton("google"); 122 | 123 | //ASSERT// 124 | mediaPageSteps.iAmRedirectedToSeleniumProfile("google"); 125 | } 126 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Attempt to set APP_HOME 4 | # Resolve links: $0 may be a link 5 | PRG="$0" 6 | # Need this for relative symlinks. 7 | while [ -h "$PRG" ]; do 8 | ls=$(ls -ld "$PRG") 9 | link=$(expr "$ls" : '.*-> \(.*\)$') 10 | if expr "$link" : '/.*' >/dev/null; then 11 | PRG="$link" 12 | else 13 | PRG=$(dirname "$PRG")"/$link" 14 | fi 15 | done 16 | SAVED="$(pwd)" 17 | cd "$(dirname \"$PRG\")/" >/dev/null 18 | APP_HOME="$(pwd -P)" 19 | cd "$SAVED" >/dev/null 20 | 21 | APP_NAME="Gradle" 22 | APP_BASE_NAME=$(basename "$0") 23 | 24 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 25 | DEFAULT_JVM_OPTS="" 26 | 27 | # Use the maximum available, or set MAX_FD != -1 to use that value. 28 | MAX_FD="maximum" 29 | 30 | warn() { 31 | echo "$*" 32 | } 33 | 34 | die() { 35 | echo 36 | echo "$*" 37 | echo 38 | exit 1 39 | } 40 | 41 | # OS specific support (must be 'true' or 'false'). 42 | cygwin=false 43 | msys=false 44 | darwin=false 45 | nonstop=false 46 | case "$(uname)" in 47 | CYGWIN*) 48 | cygwin=true 49 | ;; 50 | Darwin*) 51 | darwin=true 52 | ;; 53 | MINGW*) 54 | msys=true 55 | ;; 56 | NONSTOP*) 57 | nonstop=true 58 | ;; 59 | esac 60 | 61 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 62 | 63 | # Determine the Java command to use to start the JVM. 64 | if [ -n "$JAVA_HOME" ]; then 65 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 66 | # IBM's JDK on AIX uses strange locations for the executables 67 | JAVACMD="$JAVA_HOME/jre/sh/java" 68 | else 69 | JAVACMD="$JAVA_HOME/bin/java" 70 | fi 71 | if [ ! -x "$JAVACMD" ]; then 72 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 73 | 74 | Please set the JAVA_HOME variable in your environment to match the 75 | location of your Java installation." 76 | fi 77 | else 78 | JAVACMD="java" 79 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | 85 | # Increase the maximum file descriptors if we can. 86 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then 87 | MAX_FD_LIMIT=$(ulimit -H -n) 88 | if [ $? -eq 0 ]; then 89 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then 90 | MAX_FD="$MAX_FD_LIMIT" 91 | fi 92 | ulimit -n $MAX_FD 93 | if [ $? -ne 0 ]; then 94 | warn "Could not set maximum file descriptor limit: $MAX_FD" 95 | fi 96 | else 97 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 98 | fi 99 | fi 100 | 101 | # For Darwin, add options to specify how the application appears in the dock 102 | if $darwin; then 103 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 104 | fi 105 | 106 | # For Cygwin, switch paths to Windows format before running java 107 | if $cygwin; then 108 | APP_HOME=$(cygpath --path --mixed "$APP_HOME") 109 | CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") 110 | JAVACMD=$(cygpath --unix "$JAVACMD") 111 | 112 | # We build the pattern for arguments to be converted via cygpath 113 | ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) 114 | SEP="" 115 | for dir in $ROOTDIRSRAW; do 116 | ROOTDIRS="$ROOTDIRS$SEP$dir" 117 | SEP="|" 118 | done 119 | OURCYGPATTERN="(^($ROOTDIRS))" 120 | # Add a user-defined pattern to the cygpath arguments 121 | if [ "$GRADLE_CYGPATTERN" != "" ]; then 122 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 123 | fi 124 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 125 | i=0 126 | for arg in "$@"; do 127 | CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) 128 | CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option 129 | 130 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition 131 | eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") 132 | else 133 | eval $(echo args$i)="\"$arg\"" 134 | fi 135 | i=$((i + 1)) 136 | done 137 | case $i in 138 | 0) set -- ;; 139 | 1) set -- "$args0" ;; 140 | 2) set -- "$args0" "$args1" ;; 141 | 3) set -- "$args0" "$args1" "$args2" ;; 142 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 143 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 144 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 145 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 146 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 147 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 148 | esac 149 | fi 150 | 151 | # Escape application args 152 | save() { 153 | for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done 154 | echo " " 155 | } 156 | APP_ARGS=$(save "$@") 157 | 158 | # Collect all arguments for the java command, following the shell quoting and substitution rules 159 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 160 | 161 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 162 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 163 | cd "$(dirname "$0")" 164 | fi 165 | 166 | exec "$JAVACMD" "$@" -------------------------------------------------------------------------------- /src/test/resources/features/CustomerService.feature: -------------------------------------------------------------------------------- 1 | #/** 2 | #* Test_Automation-automationpractice 3 | #* 4 | #* @author kamil.nowocin 5 | #**/ 6 | 7 | @customerService 8 | Feature: As a user I would like to contact with customer service support 9 | #--------------------------------------------------------------------------------# 10 | # [UserStory] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-222 # 11 | #--------------------------------------------------------------------------------# 12 | 13 | Background: Navigate to Contact Us page 14 | Given I open home page 15 | And I can see automationpractice.com website 16 | When I click on Contact Us button 17 | Then I can see Contact Us form 18 | 19 | #--------------------------------------------------------------------------------# 20 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0005 21 | @non-smoke @normal @regression 22 | Scenario:[US-222]/[1] As a user I am able to send request via contact us form, all inputs are filled up 23 | Given I am on Customer Service Contact Us page form 24 | When I choose Subject Heading "Customer service" 25 | And I write an email address in contact us page 26 | And I write order reference 27 | And I write message 28 | Then I click Send button 29 | And I can see success message "Your message has been successfully sent to our team." 30 | 31 | #--------------------------------------------------------------------------------# 32 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0006 33 | @non-smoke @normal @regression 34 | Scenario:[US-222]/[2] As a user I am able to send request via contact us form, all required inputs are filled up 35 | Given I am on Customer Service Contact Us page form 36 | When I choose Subject Heading "Customer service" 37 | And I write an email address in contact us page 38 | And I write message 39 | Then I click Send button 40 | And I can see success message "Your message has been successfully sent to our team." 41 | 42 | #--------------------------------------------------------------------------------# 43 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0007 44 | @smoke @critical @regression 45 | Scenario:[US-222]/[3] As a user I am able to send request via contact us form witch attached file 46 | Given I am on Customer Service Contact Us page form 47 | When I choose Subject Heading "Customer service" 48 | And I write an email address in contact us page 49 | And I write order reference 50 | And I choose file to attach 51 | And I write message 52 | Then I click Send button 53 | And I can see success message "Your message has been successfully sent to our team." 54 | 55 | #--------------------------------------------------------------------------------# 56 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0008 57 | @non-smoke @normal @regression 58 | Scenario:[US-222]/[4] As a user I am not able to send request via contact us form, email input is invalid 59 | Given I am on Customer Service Contact Us page form 60 | When I choose Subject Heading "Customer service" 61 | And I write an invalid email address in contact us page 62 | And I write order reference 63 | And I choose file to attach 64 | And I write message 65 | Then I click Send button 66 | And I can see error message "Invalid email address." 67 | 68 | #--------------------------------------------------------------------------------# 69 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0009 70 | @non-smoke @normal @regression 71 | Scenario:[US-222]/[5] As a user I am not able to send request via contact us form, subject is missing 72 | Given I am on Customer Service Contact Us page form 73 | When I don't choose Subject Heading 74 | And I write an email address in contact us page 75 | And I write order reference 76 | And I choose file to attach 77 | And I write message 78 | Then I click Send button 79 | And I can see error message "Please select a subject from the list provided." 80 | 81 | #--------------------------------------------------------------------------------# 82 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0010 83 | @non-smoke @normal @regression 84 | Scenario:[US-222]/[6] As a user I am not able to send request via contact us form, email address is missing 85 | Given I am on Customer Service Contact Us page form 86 | When I choose Subject Heading "Customer service" 87 | And I don't write an email address 88 | And I write order reference 89 | And I choose file to attach 90 | And I write message 91 | Then I click Send button 92 | And I can see error message "Invalid email address." 93 | 94 | #--------------------------------------------------------------------------------# 95 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0011 96 | @non-smoke @normal @regression 97 | Scenario:[US-222]/[7] As a user I am not able to send request via contact us form, message input is missing 98 | Given I am on Customer Service Contact Us page form 99 | When I choose Subject Heading "Customer service" 100 | And I write an email address in contact us page 101 | And I write order reference 102 | And I choose file to attach 103 | And I don't write message 104 | Then I click Send button 105 | And I can see error message "The message cannot be blank." 106 | 107 | #--------------------------------------------------------------------------------# 108 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0012 109 | @non-smoke @normal @regression 110 | Scenario:[US-222]/[8] As a user I am not able to send request via contact us form, all inputs are missing 111 | Given I am on Customer Service Contact Us page form 112 | When I click Send button 113 | Then I can see error message "Invalid email address." -------------------------------------------------------------------------------- /src/test/resources/features/Registration.feature: -------------------------------------------------------------------------------- 1 | #/** 2 | #* Test_Automation-automationpractice 3 | #* 4 | #* @author kamil.nowocin 5 | #**/ 6 | 7 | @registration 8 | Feature: As a user I would like to register into automationpractice.com 9 | #--------------------------------------------------------------------------------# 10 | # [UserStory] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-333 # 11 | #--------------------------------------------------------------------------------# 12 | 13 | Background: Navigate to Sign Up page 14 | Given I open home page 15 | And I can see automationpractice.com website 16 | When I click on Sign in button 17 | Then I can see registration page form 18 | 19 | #--------------------------------------------------------------------------------# 20 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0013 21 | @smoke @blocker @regression 22 | Scenario:[US-333]/[1] As a user I check availability of registration page form 23 | Given I can see registration page form 24 | When I write an email address 25 | And I click on Create An Account button 26 | Then I can see account creation page form 27 | 28 | #--------------------------------------------------------------------------------# 29 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0014 30 | @smoke @critical @regression 31 | Scenario:[US-333]/[2] As a user I can create an account by filling up all fields 32 | Given I can see registration page form 33 | When I write an email address 34 | And I click on Create An Account button 35 | And I choose gender 36 | And I write my first name 37 | And I write my last name 38 | And I check if email is already written and valid 39 | And I write password 40 | And I choose date of birth 41 | And I sign in to receive newsletter and special offers 42 | And I check if my first & last name are already written and are correct 43 | And I write company name 44 | And I write my addresses 45 | And I choose country "United States" 46 | And I write city name 47 | And I choose state 48 | And I write postal code 49 | And I write additional information 50 | And I write home phone 51 | And I write mobile phone 52 | And I write my address alias 53 | And I click on Register button 54 | Then I can see welcome message 55 | 56 | #--------------------------------------------------------------------------------# 57 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0015 58 | @non-smoke @critical @regression 59 | Scenario:[US-333]/[3] As a user I can create an account by filling up only required fields 60 | Given I can see registration page form 61 | When I write an email address 62 | And I click on Create An Account button 63 | And I write my first name 64 | And I write my last name 65 | And I check if email is already written and valid 66 | And I write password 67 | And I check if my first & last name are already written and are correct 68 | And I write my address 69 | And I choose country "United States" 70 | And I write city name 71 | And I choose state 72 | And I write postal code 73 | And I write mobile phone 74 | And I write my address alias 75 | And I click on Register button 76 | Then I can see welcome message 77 | 78 | #--------------------------------------------------------------------------------# 79 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0016 80 | @non-smoke @normal @regression 81 | Scenario:[US-333]/[4] As a user I can't create an account without filling up fields 82 | Given I can see registration page form 83 | When I write an email address 84 | And I click on Create An Account button 85 | And I click on Register button 86 | Then I can see registration error 87 | 88 | #--------------------------------------------------------------------------------# 89 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0017 90 | # This scenario is created as "smart one", you can choose any of required field to be missing. 91 | # Simply, just leave one and only one of data section as blank one. 92 | @non-smoke @normal @regression 93 | Scenario:[US-333]/[5] As a user I can't create an account, when one of required fields is missing 94 | Given I can see registration page form 95 | When I write an email address 96 | And I click on Create An Account button 97 | And I write following data to registration form 98 | | First Name | Last Name | Password | Address | City | State | Postal Code | Country | Mobile Phone | 99 | | Thor | Odinson | #passwd123 | | Anchorage | Alaska | 99503 | United States | 907-748-2005 | 100 | And I check if email is already written and valid 101 | And I check if my first & last name are already written and are correct 102 | And I write my address alias 103 | And I click on Register button 104 | Then I can see warning message about missing "one element" input 105 | 106 | #--------------------------------------------------------------------------------# 107 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0018 108 | @smoke @critical @regression 109 | Scenario:[US-333]/[6] As a user I can't create an account, when email is already in database 110 | Given I can see registration page form 111 | When I write an email address which is already in database 112 | And I click on Create An Account button 113 | Then I can see registration error 114 | 115 | #--------------------------------------------------------------------------------# 116 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0019 117 | @non-smoke @critical @regression 118 | Scenario:[US-333]/[7] As a user I can't create an account, when email has wrong format 119 | Given I can see registration page form 120 | When I write an invalid email address 121 | And I click on Create An Account button 122 | Then I can see create an account error -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: linux 2 | language: java 3 | jdk: 4 | - oraclejdk14 5 | env: 6 | matrix: 7 | - DISPLAY=:99.0 8 | global: 9 | #$GITHUB_TOKEN 10 | - secure: vt+xYgydmvdzHQvO9QcNehtztHLkad89iunw7ebrmPEXgjSNwqOVHjSzRvASazYht9iq+kIs4reEQUS2i3+0Sq+VvyP26g6jGmrClXbnRWBrk84MHDbW0Ee+5f8RwT471QAT+GQrXK9ELLM6x9cfeJZsUsowGR0d+miEE7VYy29cYzEjQ8KVw5b2KVW9KL7c1bqQHDu9zsVSxNEzZs8KbQ86W1vymUF1F/KMnUWs6oyuH/STohAH8cYPmcK3p/d2wtnuVVny/OAXy5V6fkq9F/kycjRvj5fwkwPdPzHwACzoY+NDe/UoA/A0bk99b0Sk/jz7CaiBhjK0pBK2SvelxR+90VLYcnLSy70x5o2ET4HgkikP8r5nKX4r2cdQiVWL51GB8B2ooI9+h8fV8xMwYXlRJAxgzjuTQFpGc7tATD34234LUWzHxqbTOEWiVZqfCrPVNeQ4SbUg3ud+ETiFQ00+ELGth7Usbk1eUHGKIUi3kWR/xhBkl5/pZZswAEXvAsRfdJzncm65Xrv1VAgIW90+dMTQZmEne7xt+KYYllnqqIbo3s2ah78RUUPuC+r7TxAdE9KnkiPUipa/x1LUvNIf969BaV+RYPEjRJy5eKFm2eGqduXMCh8BjHbuS2Ohcbrm7YIXbPs84N6LqCiGdfQQzvTKuIPmglGynADpHvc= 11 | #$SLACK_TOKEN 12 | - secure: O1CQhHHDwhKZMyB/l4xG/ZdKKCW04rLzfa+H5X1Sgi0ALiOkwMt5j56XC6J97a6OOjtXvJjYHZt+BdN7eCjb9DhOxpi5tWgTSloq9kPmhJymr1br1c5SsXxFDbtJPcOYxxDlvkC2aJH+ocWX7ikxoMzSG+FZ+sHolhdX7kkUWOgB6cf4h8ltlNY01LH+jjhwp7lbnJiqjMptT0V3U0oL7i6QL48ZOUDBVxOBaDERDSsW095fVvwGoY0/eme5caeSdfM6FUPKni2VOxSAoBOu0yabtDwRqC/EXr1E4ME96YQvIRRnIf5vO8Situ2NraVnh1lWU5QsInpCstUh6RfAl4kq6QDRcKFaf/0NGQAKY/4JCS2+fKhTZJVZdRNoXvhqM+gs0eR8/JgunVbCSbxo6sI0QTGAFszh8oaCSsp/ZbZJNiWWvdKNLE0QLHpOo092smMf+RaMiyoKkPBM9Qvu/nKfFWVo9ooeSVSvILXZD6i0ku5oMdr6Al94mTMMFPGpGSTq0pjf8IJ7UDg3vxmex76vHtVG3yNyjJy5YaR4+AKQQqewfKiAqSOrzVq/Be0nLLerpf401S2MC8h0HkaWsMujzuQo30Q1N6H66hlkg7ubl66vvh4J8/ITNaUUPM4WFyZawl7EEXu8HUQ0SXWBZhvF/RxSOI2Orw+iHI7RVwg= 13 | #$USER_NAME 14 | - secure: rku4gJTH9mT6rZgCv9mx/IH/p//iIf17Y471I6E3AbJsUe3fWyJnGymMV+jyxXw/66AtT0EP/dlrXS/vdbBkE0W/SgRKWoUUNPbsBoAfU1QC6btz1H9uiNXZcV12LB2rnXCwfmK7uPP9FL7dVCqGO+QhU1bVLH9JCDY7/5BpBScFYTyin5ZCMzYjlVhFKyx2kmTbOjj/xdBIWfwHUSgMZa8C2Tn3YvecwRMGNRdqCts0E+setpr/LV2zofr3KQO/1zCD++KeD+apP4NjHNNHfDGsdL5f6WX/fdyTDewEaTIxCXkTq147Sn6QW0tbZG9aRNkkE4Hy3fYTveXYMHFgHDJKeYaHZXqZCSzcvTrnc7Gn0ld9njJU8ChgzKYKNWBbnHPErXkKcNC4I1WDyiMG1rRJBETNvW2kQA6spbNhlVnExWtQu2lzKtVIz+D2RML4385CHF70z83tPNYriMByB8NiIFW4/dcfqYeTtzkM6oPHDiAZ/sJSxlHE4/L3o2zpU2krLxQKYpg+n6xa2ltGLe1k4nKujnma99snquS4f8yBhAcO5AHns3G4iYhUQFkEzblPd6zP5W2TdLiw4l5xADCbNav6GZIh8t6DG78mncWg+jFJ4Hm/c9pLaQxGV/rNVlT1ohn6zgt1L5vG92vyh8HJwSLFIFbd1uYa78osbII= 15 | #$ACCESS_KEY 16 | - secure: qekq6WCfUj8iPXcucPIQ4mipHtqem3Mh5iHJl6Isn2+7LySQCLLzr68R5puLMrS1p4Ml/6cQdsAwAE9QlCoYxneT1BSYaY6sJJ8z9NsHERkERpf/CekNQ9cvKRZ2dG0aPqnMbop2v3JfwTCYNhGFmsGV0/pEcvPKn7cvsfoJiJccRsBc9g1lXO47az8z0JjHeuZ19YkxK/zf0VkbPJ3Z9wZ+PdIlABf/eyiU8Krmh6qKAHU0gbic2KzHmCUGucQA8REuDUxzAOsAxhaRSum5BEO6Z1HfbAC3hFkNJFxfQdJjclGLLVU9qcXia9jkfqNW1k/jGH61KtLgKl2Si9wiQu8jxq152HjgbJKpi7fqVctsMtvjrpSeuJ1R/AL4T4ubx4pgmbZj9MRvAbTfKAxFj27fihItfSjWhsME3BvH22ewDBUxW5N3wJ3nSaClvoESocDq/OVlnOTxSY997iewGGQg/X5tW8w9QDhVLpGtR6VCsURQQEDKfXwDYHkz4HH5d4XNPFsDEyHLBSeYLJETT8W6Q7uHYDhET1XOXV9iAyquijwpF/1h8XvCWSZBLcbWfbz7COMpNbcsQl+QoM+IvBxBPP/LZNp9ipX/4mfuvIP8mD/1GefKXmyamSZS1ZK7S3FVqi+kl4jfSPKNVufE5dw39CUA5ztzZnXCND6ns+Q= 17 | #LINUX VERSION 18 | dist: bionic 19 | #GUI & VIRTUAL BROWSER 20 | services: 21 | - xvfb 22 | notifications: 23 | slack: 24 | rooms: 25 | - secure: E+UlNohgriwhUd5FlWkdH04YqNMdK2R3f2gjqLO9diKpgJr5i3ITIhm18i4jJC4dcE95mvNGYroznb1G/sLBiEAPOe2JT4lToKjWEB+Iup+juqskDnn7E0RVbc73WrYhgFSnMMxAXmzHWJCpH4otW28gTC431m3yswwQeb30A+u1dmmsuHm8jK4vwjYs+aBb55OJj48ReChvpoM6mrF81u+kB+/KFKdRJ+6iMC9oGv1ogE3ejrCLcf3CoqEW2eDGKRG+luwiGgA1+UwPKuBvtg2gHyuXsZ0Ew4IMU7YIElc3tAAbrPSbH60im3GB8YhHAinl2aJXsmBrEWTDRG3tzu42RhkJ3dNSaxsYweL9/deX76YXo9OgdRf2a2L9SV00T5m1PbaxvDxmPfh7qa3JYTjYTUMQOoVTdwKyXOHCQaXxw2oWooTaUxkBeQY4eME+eCefOzkfBiLde8HFgUYoAzZDg0GiRHFx525qfeS9UgAHKIq2aHLzxwbL1P+d/rzcpSAfDFGl+vD+veGCgFW4Jtqn66a1BFQgzTwpzgpxV9+LTsAIkZ6Xzq+XSxwJprZdkolfug2cNM8dLlbvzGz+I4Ptt78wMVaGMxkWi/E7EshpbLCE0gSxXUDOAVT5yF340sfJVcGFqnAD12NekW19KL4IrgelxruS4i5inuuIm5Q= 26 | on_pull_requests: true 27 | on_success: always 28 | on_failure: always 29 | template: 30 | - "Repository: `%{repository_slug}`" 31 | - "Deploy status: *%{result}*, build number (<%{build_url}|#%{build_number}>)" 32 | - "Author: *%{author}*, for commit (<%{compare_url}|%{commit}>) on branch: `%{branch}`" 33 | - "Commit message: `%{commit_message}`" 34 | - "Output message: *%{message}* Execution time: *%{duration}*." 35 | email: 36 | on_success: never 37 | on_failure: always 38 | addons: 39 | chrome: stable 40 | #DOWNLOAD AND INSTALL ALL REQUIRED DRIVERS 41 | install: 42 | #- wget -N http://chromedriver.storage.googleapis.com/81.0.4044.138/chromedriver_linux64.zip -P 43 | #- unzip chromedriver_linux64.zip -d 44 | - npm install -g allure-commandline --save-dev 45 | before_script: 46 | - echo ======================================================================== 47 | - echo =========================BUILD EXECUTION STARTED======================== 48 | - echo ======================================================================== 49 | #RUN GRADLE 50 | script: 51 | - ./gradlew test -Dtravis.buildNumber=$TRAVIS_BUILD_NUMBER -Dtravis.buildURL=$TRAVIS_BUILD_WEB_URL -Dtravis.branch=$TRAVIS_BRANCH -Dtravis.osName=$TRAVIS_OS_NAME -Dtravis.jdkVersion=$TRAVIS_JDK_VERSION -Dtravis.slack=$SLACK_TOKEN 52 | #THIS COMMAND WOULD RUN TESTS ON BROWSERSTACK 53 | #- ./gradlew test -Dtests.executor=browserstack -Dbrowserstack.hostURL=https://$USER_NAME:$ACCESS_KEY@hub-cloud.browserstack.com/wd/hub -Dremote.browser=chrome 54 | after_script: 55 | - echo ======================================================================== 56 | - echo ========================BUILD EXECUTION FINISHED======================== 57 | - echo ======================================================================== 58 | - chmod 777 .travis/deploy.sh 59 | - echo ======================================================================== 60 | - echo =========================UPLOADING TEST REPORTS========================= 61 | - echo ======================================================================== 62 | - .travis/deploy.sh 63 | - echo ======================================================================== 64 | - echo ===============================DONE 100%================================ 65 | - echo ======================================================================== -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![IMG](https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/master/src/test/resources/files/images/readme_banner.jpg) 2 | ![JAVA](https://img.shields.io/badge/language-java-critical?style=flat-square) 3 | ![ALLURE](https://img.shields.io/badge/Allure%20Report-2.8.1-orange.svg?style=flat-square) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT) 5 | [![Build Status](https://img.shields.io/travis/kamil-nowocin/Test_Automation-automationpractice/master.svg?style=flat-square)](https://travis-ci.com/kamil-nowocin/Test_Automation-automationpractice) 6 | ![GitHub last commit](https://img.shields.io/github/last-commit/kamil-nowocin/Test_Automation-automationpractice?style=flat-square) 7 | ![GitHub release (latest by date)](https://img.shields.io/github/v/release/kamil-nowocin/Test_Automation-automationpractice?style=flat-square) 8 | ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/kamil-nowocin/Test_Automation-automationpractice?style=flat-square) 9 | [![LinkedIn](https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square&logo=linkedin&colorB=555)](https://linkedin.com/in/kamil-nowocin) 10 | # Test automation - http://www.automationpractice.com 11 | **Design Pattern:** Page Object Model with loadable components(POC) & AAA 12 | **Following tools were used in this framework:** 13 | Java, Selenium, TestNG, Cucumber, REST Assured, Gradle, Travis CI, Allure Reports, Slack API, SeleniumGrid, WebDriverManager, Faker & MockNeat, BrowserStack, GitHub Pages 14 | * [About project](#about-project) 15 | * [Features](#features) 16 | * [How to run tests](#how-to-run-tests) 17 | + [TestNG](#testng) 18 | + [Cucumber](#cucumber) 19 | * [Test results & Test logs](#test-results--test-logs) 20 | + [CI/CD](#cicd) 21 | + [Localhost](#localhost) 22 | + [TestNG & Cucumber](#testng--cucumber) 23 | * [Logger (Slack Bot)](#logger-slack-bot) 24 | + [CI/CD](#cicd-1) 25 | + [Localhost](#localhost-1) 26 | * [SeleniumGrid](#selenium-grid-poc) 27 | + [CI/CD](#cicd-2) 28 | + [Localhost](#localhost-2) 29 | + [How to run tests](#how-to-run-tests-1) 30 | * [Authors](#authors) 31 | * [License](#license) 32 | ## ABOUT PROJECT 33 | Project made in my spare time to develop my skills in automation testing. 34 | You don't have to download any WebDrivers - I'm using WebDriverManager, drivers will be downloaded by gradle. 35 | Supported tests executors: 36 | - *Chrome* 37 | - *Firefox* 38 | - *Opera* 39 | - *Safari* 40 | - *Edge* 41 | - *Internet Explorer* 42 | - *SeleniumGrid* 43 | - *BrowserStack* 44 | ## FEATURES 45 | - Support for Allure Report 46 | - Support for Slack Bot 47 | - Support for SeleniumGrid 48 | - Support for Parallel Testing 49 | - Support for BrowserStack 50 | - Support for WebDriverManager 51 | - Support for Fake & Mock data 52 | - Support for .xlsx files 53 | ## HOW TO RUN TESTS 54 | There are multiple ways to run tests from this build. It all depends on what do you want to do: 55 | ### TestNG 56 | - Right click on `TestNG.xml` file, and Run -> This will run all tests attached to specific xml runner 57 | - In terminal type `./gradlew test` -> This will run all tests from tests package.`(src/test/java/tests)` 58 | You can add some environment settings, before you run tests, e.g: 59 | - `-Dtests.executor="YOUR_HOST_NAME"` -> available hosts: Chrome, Firefox, Opera, Safari, Edge, IE, Safari, GRID, BrowserStack 60 | _**This is the best option to run tests, all tools, features are working well while running tests via this commend**_ 61 | ### Cucumber 62 | - Right click on `.feature` file, and Run -> This will run `.feature` file on default settings 63 | - In terminal type `./gradlew cucumber` -> This will run all `.feature` files on default settings 64 | You can add some environment settings, before you run tests, e.g: 65 | - `-Dtests.executor="YOUR_HOST_NAME"` -> available hosts: Chrome, Firefox, Opera, Safari, Edge, IE, Safari, GRID, BrowserStack 66 | - In terminal type `./gradlew cucumber -Dcucumber.filter.tags="@YOUR_TAG"` -> This will run all `.feature` scenarios which provided tag 67 | - Right click on `CucumberRunner` file, and Run -> This will run all `.feature` files on default settings 68 | - *This is highly unrecommended option since it's an experimental file and doesn't work well, check build.gradle for more information* 69 | - Create your own runner :hammer_and_wrench: 70 | ## TEST RESULTS & TEST LOGS 71 | ### CI/CD 72 | After each CI/CD cycle run, tests results will be automatically uploaded to [kamil_nowocin.github.io/Test_Automation](https://kamil-nowocin.github.io/Test_Automation-automationpractice/) 73 | ### Localhost 74 | After each LOCAL cycle run two types of log information are saved inside repository, together with tests results 75 | ### TestNG & Cucumber 76 | - Detailed logs in logs directory 77 | - Colorful logs in testdata.xlsx file 78 | - Allure HTML report in build/allure-results directory 79 | 80 | In terminal type `allure generate build/allure-results --clean` to generate Allure tests results 81 | *Allure tests results available for running tests via: CucumberRunner, `./gradlew test` or TestMethod with annotation @Test (src/test/java/tests)* 82 | ![Imgur](https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/master/src/test/resources/files/images/allure_gif.gif) 83 | ## LOGGER (Slack Bot) 84 | ### CI/CD 85 | You are able to see real time summary of TestNG suite execution on [Slack workspace](https://testautomation-travis.slack.com) 86 | ### Localhost 87 | Not available 88 | 89 | | FAIL MESSAGE | PASS MESSAGE | 90 | | ------------- | ------------- | 91 | | ![IMG](https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/master/src/test/resources/files/images/slack_bot_fail.png) | ![IMG](https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/master/src/test/resources/files/images/slack_bot_pass.png) | 92 | ## SELENIUM GRID (POC) 93 | ### CI/CD 94 | Not available 95 | ### Localhost 96 | Right now it's only available for a local host, and **it's POC feature**, however you are able to check how it works 97 | ### HOW TO RUN TESTS 98 | 1. Run SeleniumGridRunner 99 | 2. Make sure that SeleniumGrid is running properly, check http://localhost:4444/grid/console 100 | 3. In terminal type `./gradlew test -Dtests.executor=grid -Dremote.browser="YOUR_REMOTE_BROWSER"` 101 | ## AUTHORS 102 | - **Kamil Nowocin** - *Initial work* - [Kamil Nowocin](https://github.com/kamil-nowocin) 103 | ## LICENSE 104 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 105 | -------------------------------------------------------------------------------- /src/test/java/tests/WebAPP/Authentication_Tests.java: -------------------------------------------------------------------------------- 1 | package tests.WebAPP; 2 | 3 | import com.buildListeners.TestNGListener; 4 | import com.buildSettings.ContextInjection; 5 | import com.buildSettings.ExcelEnvironment; 6 | import com.steps.AuthenticationPageSteps; 7 | import com.steps.MainPageSteps; 8 | import com.steps.RegistrationPageSteps; 9 | import com.steps.hooks.WEB_Hooks; 10 | import io.qameta.allure.*; 11 | import org.testng.annotations.Listeners; 12 | import org.testng.annotations.Test; 13 | 14 | /** 15 | * Test_Automation-automationpractice 16 | * 17 | * @author kamil.nowocin 18 | **/ 19 | 20 | @Epic("Web App Tests") 21 | @Feature("LOGIN TESTS") 22 | @Listeners({TestNGListener.class}) 23 | public class Authentication_Tests extends WEB_Hooks { 24 | 25 | @Issue("TAP-0001") 26 | @TmsLink("STORY-111") 27 | @Story("POSITIVE FLOW") 28 | @Owner("Kamil Nowocin") 29 | @Severity(SeverityLevel.CRITICAL) 30 | @Description("[US-111]/[1] As a user I can log into automationpractice.com using registered email \"thor.odinson@example.com\" & password \"12345\"") 31 | @Test(description = "[US-111]/[1] I can log into automationpractice.com using registered email \"thor.odinson@example.com\" & password \"12345\"", 32 | priority = 0) 33 | public void test_1() throws Throwable { 34 | //ARRANGE// 35 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 36 | final MainPageSteps mainPageSteps = new MainPageSteps(); 37 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 38 | final AuthenticationPageSteps authenticationPageSteps = new AuthenticationPageSteps(); 39 | 40 | excelEnvironment.saveTestResultsXLSX(1); 41 | 42 | //ACT// 43 | mainPageSteps.iOpenHomePage(); 44 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 45 | registrationPageSteps.iClickOnSignInButton(); 46 | authenticationPageSteps.iCanSeeLoginForm(); 47 | authenticationPageSteps.iEnterLogin("thor.odinson@example.com"); 48 | authenticationPageSteps.iEnterPassword("12345"); 49 | authenticationPageSteps.iClickOnSubmitButton(); 50 | 51 | //ASSERT 52 | registrationPageSteps.iCanSeeWelcomeMessage(); 53 | } 54 | 55 | @Issue("TAP-0002") 56 | @TmsLink("STORY-111") 57 | @Story("NEGATIVE FLOW") 58 | @Severity(SeverityLevel.NORMAL) 59 | @Owner("Kamil Nowocin") 60 | @Description("[US-111]/[2] As a user I can't log into automationpractice.com using email \"thanos.ALars@example.com\" & password \"12345\"") 61 | @Test(description = "[US-111]/[2] I can't log into automationpractice.com using email \"thanos.ALars@example.com\" & password \"12345\"", 62 | priority = 0) 63 | public void test_2() throws Throwable { 64 | //ARRANGE// 65 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 66 | final MainPageSteps mainPageSteps = new MainPageSteps(); 67 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 68 | final AuthenticationPageSteps authenticationPageSteps = new AuthenticationPageSteps(); 69 | 70 | excelEnvironment.saveTestResultsXLSX(2); 71 | 72 | //ACT// 73 | mainPageSteps.iOpenHomePage(); 74 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 75 | registrationPageSteps.iClickOnSignInButton(); 76 | authenticationPageSteps.iCanSeeLoginForm(); 77 | authenticationPageSteps.iEnterLogin("thanos.ALars@example.com"); 78 | authenticationPageSteps.iEnterPassword("12345"); 79 | authenticationPageSteps.iClickOnSubmitButton(); 80 | 81 | //ASSERT// 82 | authenticationPageSteps.iCanSeeWarningMessageWithInclude("Authentication failed"); 83 | } 84 | 85 | @Issue("TAP-0003") 86 | @TmsLink("STORY-111") 87 | @Story("NEGATIVE FLOW") 88 | @Owner("Kamil Nowocin") 89 | @Severity(SeverityLevel.NORMAL) 90 | @Description("[US-111]/[2] As a user I can't log into automationpractice.com using email \"thor.odinson@example.com\" & password \"null\"") 91 | @Test(description = "[US-111]/[3] I can't log into automationpractice.com using email \"thor.odinson@example.com\" & password \"null\"", 92 | priority = 0) 93 | public void test_3() throws Throwable { 94 | //ARRANGE// 95 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 96 | final MainPageSteps mainPageSteps = new MainPageSteps(); 97 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 98 | final AuthenticationPageSteps authenticationPageSteps = new AuthenticationPageSteps(); 99 | 100 | excelEnvironment.saveTestResultsXLSX(3); 101 | 102 | //ACT// 103 | mainPageSteps.iOpenHomePage(); 104 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 105 | registrationPageSteps.iClickOnSignInButton(); 106 | authenticationPageSteps.iCanSeeLoginForm(); 107 | authenticationPageSteps.iEnterLogin("thor.odinson@example.com"); 108 | authenticationPageSteps.iEnterPassword(""); 109 | authenticationPageSteps.iClickOnSubmitButton(); 110 | 111 | //ASSERT// 112 | authenticationPageSteps.iCanSeeWarningMessageWithInclude("Password is required"); 113 | } 114 | 115 | @Issue("TAP-0004") 116 | @TmsLink("STORY-111") 117 | @Story("NEGATIVE FLOW") 118 | @Owner("Kamil Nowocin") 119 | @Severity(SeverityLevel.NORMAL) 120 | @Description("[US-111]/[2] As a user I can't log into automationpractice.com using email \"null\" & password \"12345\"") 121 | @Test(description = "[US-111]/[4] I can't log into automationpractice.com using email \"null\" & password \"12345\"", 122 | priority = 0) 123 | public void test_4() throws Throwable { 124 | //ARRANGE// 125 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 126 | final MainPageSteps mainPageSteps = new MainPageSteps(); 127 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 128 | final AuthenticationPageSteps authenticationPageSteps = new AuthenticationPageSteps(); 129 | 130 | excelEnvironment.saveTestResultsXLSX(4); 131 | 132 | //ACT// 133 | mainPageSteps.iOpenHomePage(); 134 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 135 | registrationPageSteps.iClickOnSignInButton(); 136 | authenticationPageSteps.iCanSeeLoginForm(); 137 | authenticationPageSteps.iEnterLogin(""); 138 | authenticationPageSteps.iEnterPassword("12345"); 139 | authenticationPageSteps.iClickOnSubmitButton(); 140 | 141 | //ASSERT// 142 | authenticationPageSteps.iCanSeeWarningMessageWithInclude("An email address required"); 143 | } 144 | } -------------------------------------------------------------------------------- /src/test/java/com/steps/SearchPageSteps.java: -------------------------------------------------------------------------------- 1 | package com.steps; 2 | 3 | import com.buildSettings.ContextInjection; 4 | import com.buildSettings.TestCommons; 5 | import com.buildSettings.TestEnvironment; 6 | import com.google.common.collect.Ordering; 7 | import com.pages.MainPage; 8 | import com.pages.SearchPage; 9 | import io.cucumber.java.en.And; 10 | import io.cucumber.java.en.Then; 11 | import io.cucumber.java.en.When; 12 | import io.qameta.allure.Step; 13 | import org.openqa.selenium.WebElement; 14 | import org.testng.Assert; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | /** 20 | * Test_Automation-automationpractice 21 | * 22 | * @author kamil.nowocin 23 | **/ 24 | 25 | public class SearchPageSteps extends TestEnvironment { 26 | 27 | private final MainPage mainPage = new MainPage().get(); 28 | private final TestCommons testCommons = new TestCommons(); 29 | private final SearchPage searchPage = new SearchPage().get(); 30 | 31 | @Step("I search for phrase *{0}*") 32 | @When("I search for phrase {string}") 33 | public void iSearchForPhrase(String searchPhrase) throws Throwable { 34 | //ACT// 35 | testCommons.customSendKeys(mainPage.searchBoxInput, searchPhrase); 36 | logger.info(String.format("User search for: \"%S\"", searchPhrase)); 37 | 38 | //ASSERT// 39 | Assert.assertEquals(mainPage.searchBoxInput.getAttribute("value").toLowerCase(), 40 | searchPhrase.toLowerCase(), ContextInjection.VALUE_ERROR); 41 | } 42 | 43 | @Step("I click on search icon") 44 | @And("I click on search icon") 45 | public void iClickOnSearchIcon() throws Throwable { 46 | testCommons.customClick(mainPage.searchBoxSubmit); 47 | } 48 | 49 | @Step("I can see numbers of results equals to *{0}*") 50 | @Then("I can see numbers of results equals to {string}") 51 | public void iCanSeeNumbersOfResultsEqualsTo(String expectedCountOfResults) throws Throwable { 52 | //ARRANGE// 53 | testCommons.waitForElementToBeVisible(searchPage.searchResultsNumber); 54 | final String actualCountOfResults = searchPage.searchResultsNumber.getText().replaceAll("[^\\d]", ""); 55 | 56 | //ACT// 57 | if (expectedCountOfResults.equals("0")) { 58 | Assert.assertTrue(testCommons.isElementVisible(searchPage.noResultsWereFoundHeader), 59 | String.format(ContextInjection.VIEW_ERROR, "No results were found header")); 60 | } 61 | logger.info(String.format("Found results: \"%S\", expected: \"%S\"", actualCountOfResults, expectedCountOfResults)); 62 | 63 | //ASSERT// 64 | Assert.assertEquals(actualCountOfResults, expectedCountOfResults, String.format(ContextInjection.RESULTS_ERROR, 65 | actualCountOfResults, expectedCountOfResults)); 66 | } 67 | 68 | @Step("I can see that every results which have been found contains phrase *{0}*") 69 | @And("I can see that every results which have been found contains phrase {string}") 70 | public void iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase(String searchPhrase) throws Throwable { 71 | //ARRANGE// 72 | String[] listOfSearchedPhrases = searchPhrase.toLowerCase().split("[\\s]"); 73 | 74 | //ACT// 75 | if (!searchPage.noResultsWereFoundHeader.isDisplayed()) { 76 | for (WebElement productName : searchPage.productNames) { 77 | for (String singlePhrase : listOfSearchedPhrases) { 78 | //ASSERT// 79 | Assert.assertTrue(productName.getText().toLowerCase().contains(singlePhrase.toLowerCase()), ContextInjection.SEARCH_ERROR); 80 | } 81 | } 82 | } else { 83 | Assert.assertTrue(testCommons.isElementVisible(searchPage.noResultsWereFoundHeader), 84 | String.format(ContextInjection.VIEW_ERROR, "No result header")); 85 | } 86 | } 87 | 88 | @Step("I select from Dropdown Sort by *{0}*") 89 | @Then("I select from Dropdown Sort by {string}") 90 | public void iSelectFromDropdownSortBy(String sortBy) throws Throwable { 91 | //ACT// 92 | switch (sortBy.toLowerCase()) { 93 | case "price: lowest first": 94 | testCommons.selectFromDropdownByValue("price:asc", searchPage.sortByDropdown); 95 | break; 96 | case "price: highest first": 97 | testCommons.selectFromDropdownByValue("price:desc", searchPage.sortByDropdown); 98 | break; 99 | case "product name: a to z": 100 | testCommons.selectFromDropdownByValue("name:asc", searchPage.sortByDropdown); 101 | break; 102 | case "product name: z to a": 103 | testCommons.selectFromDropdownByValue("name:desc", searchPage.sortByDropdown); 104 | break; 105 | default: 106 | throw new IllegalStateException(String.format(ContextInjection.INPUT_ERROR, sortBy.toUpperCase())); 107 | } 108 | logger.info(String.format("Chosen sort option: \"%S\"", sortBy)); 109 | 110 | //ASSERT// 111 | Assert.assertEquals(searchPage.readSortByDropdown.getText().toLowerCase(), sortBy.toLowerCase(), ContextInjection.VALUE_ERROR); 112 | } 113 | 114 | @Step("I can see that results are correctly sorted by *{0}*") 115 | @And("I can see that results are correctly sorted by {string}") 116 | public void iCanSeeThatResultsAreCorrectlySortedBy(String sortedBy) throws Throwable { 117 | //ARRANGE// 118 | List arrayList = new ArrayList<>(); 119 | 120 | //ACT// 121 | logger.info(String.format("Actual sort option: \"%S\"", sortedBy)); 122 | switch (sortedBy.toLowerCase()) { 123 | case "price: lowest first": 124 | for (WebElement productPrices : searchPage.productPrices) { 125 | arrayList.add(productPrices.getText().replaceAll("[^$0-9.]", "")); 126 | } 127 | List lowestPriceList = Ordering.natural().sortedCopy(arrayList); 128 | Assert.assertEquals(arrayList, lowestPriceList, String.format(ContextInjection.SORTING_ERROR, sortedBy)); 129 | break; 130 | case "price: highest first": 131 | for (WebElement productPrices : searchPage.productPrices) { 132 | arrayList.add(productPrices.getText().replaceAll("[^$0-9.]", "")); 133 | } 134 | List highestPriceList = Ordering.natural().reverse().sortedCopy(arrayList); 135 | Assert.assertEquals(arrayList, highestPriceList, String.format(ContextInjection.SORTING_ERROR, sortedBy)); 136 | break; 137 | case "product name: a to z": 138 | for (WebElement productName : searchPage.productNames) { 139 | arrayList.add(productName.getText()); 140 | } 141 | List sortedNames = Ordering.natural().sortedCopy(arrayList); 142 | Assert.assertEquals(arrayList, sortedNames, String.format(ContextInjection.SORTING_ERROR, sortedBy)); 143 | break; 144 | case "product name: z to a": 145 | for (WebElement productName : searchPage.productNames) { 146 | arrayList.add(productName.getText()); 147 | } 148 | List reverseSortedNames = Ordering.natural().reverse().sortedCopy(arrayList); 149 | Assert.assertEquals(arrayList, reverseSortedNames, String.format(ContextInjection.SORTING_ERROR, sortedBy)); 150 | break; 151 | default: 152 | throw new IllegalStateException(String.format(ContextInjection.INPUT_ERROR, sortedBy.toUpperCase())); 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /src/test/java/tests/WebAPP/ShoppingLoggedUser_Tests.java: -------------------------------------------------------------------------------- 1 | package tests.WebAPP; 2 | 3 | import com.buildListeners.TestNGListener; 4 | import com.buildSettings.ContextInjection; 5 | import com.buildSettings.ExcelEnvironment; 6 | import com.steps.MainPageSteps; 7 | import com.steps.RegistrationPageSteps; 8 | import com.steps.ShoppingLoggedUserSteps; 9 | import com.steps.hooks.WEB_Hooks; 10 | import io.cucumber.datatable.DataTable; 11 | import io.qameta.allure.*; 12 | import org.testng.annotations.Listeners; 13 | import org.testng.annotations.Test; 14 | 15 | import java.util.Arrays; 16 | import java.util.Collections; 17 | import java.util.List; 18 | 19 | /** 20 | * Test_Automation-automationpractice 21 | * 22 | * @author kamil.nowocin 23 | **/ 24 | 25 | @Epic("Web App Tests") 26 | @Feature("SHOPPING TESTS") 27 | @Listeners({TestNGListener.class}) 28 | public class ShoppingLoggedUser_Tests extends WEB_Hooks { 29 | 30 | @Issue("TAP-0039") 31 | @TmsLink("STORY-666") 32 | @Story("POSITIVE FLOW") 33 | @Owner("Kamil Nowocin") 34 | @Severity(SeverityLevel.CRITICAL) 35 | @Description("[US-666]/[1] As a user I would like to buy new \"Faded Short Sleeve T-shirts\"") 36 | @Test(description = "[US-666]/[1] I would like to buy new \"Faded Short Sleeve T-shirts\"", 37 | priority = 0) 38 | public void test_1() throws Throwable { 39 | //ARRANGE// 40 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 41 | final MainPageSteps mainPageSteps = new MainPageSteps(); 42 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 43 | final ShoppingLoggedUserSteps shoppingLoggedUserSteps = new ShoppingLoggedUserSteps(new ContextInjection()); 44 | 45 | excelEnvironment.saveTestResultsXLSX(39); 46 | 47 | List> orderDetails = Arrays.asList 48 | ( 49 | Arrays.asList("Quantity", "Size", "Colour"), 50 | Arrays.asList("5", "M", "Blue") 51 | ); 52 | DataTable orderDetailsDataTable = DataTable.create(orderDetails); 53 | 54 | List> paymentDetails = Arrays.asList 55 | ( 56 | Collections.singletonList("Payment Method"), 57 | Collections.singletonList("Pay by check") 58 | ); 59 | DataTable paymentDetailsDataTable = DataTable.create(paymentDetails); 60 | 61 | //ACT// 62 | mainPageSteps.iOpenHomePage(); 63 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 64 | mainPageSteps.iAmLoggedAsCustomerUsingPassword("thor.odinson@example.com", "12345"); 65 | registrationPageSteps.iCanSeeWelcomeMessage(); 66 | mainPageSteps.iAmOnMyAccountDetailsPage(); 67 | shoppingLoggedUserSteps.iClickOnButtonFromSubMenu("Women"); 68 | shoppingLoggedUserSteps.iClickOnFollowingProduct("Faded Short Sleeve T-shirts"); 69 | shoppingLoggedUserSteps.iChooseFollowingDetailsOfMyOrder(orderDetailsDataTable); 70 | shoppingLoggedUserSteps.iClickOnAddToCartButton(); 71 | shoppingLoggedUserSteps.iCanSeeModalWhereIAmAbleToSeeDetailedDataAboutMyPurchase(); 72 | shoppingLoggedUserSteps.iClickOnProceedToCheckoutButtonFromModal(); 73 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Your shopping cart"); 74 | shoppingLoggedUserSteps.iClickOnProceedToCheckoutButtonFromShoppingCart(); 75 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Addresses"); 76 | shoppingLoggedUserSteps.iWriteCommentAboutMyOrder(); 77 | shoppingLoggedUserSteps.iClickOnProceedToCheckoutButtonFromShoppingCart(); 78 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Shipping"); 79 | shoppingLoggedUserSteps.iChooseShippingOption("My carrier"); 80 | shoppingLoggedUserSteps.iClickOnTermsOfServiceCheckbox(); 81 | shoppingLoggedUserSteps.iClickOnProceedToCheckoutButtonFromShoppingCart(); 82 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Your payment method"); 83 | shoppingLoggedUserSteps.iChoosePaymentMethod(paymentDetailsDataTable); 84 | shoppingLoggedUserSteps.iClickOnIConfirmMyOrderButton(); 85 | 86 | //ASSERT 87 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Order confirmation"); 88 | } 89 | 90 | @Issue("TAP-0040") 91 | @TmsLink("STORY-666") 92 | @Story("POSITIVE FLOW") 93 | @Owner("Kamil Nowocin") 94 | @Severity(SeverityLevel.CRITICAL) 95 | @Description("[US-666]/[2] As a user I would like to buy new \"Blouse\"") 96 | @Test(description = "[US-666]/[2] I would like to buy new \"Blouse\"", 97 | priority = 0) 98 | public void test_2() throws Throwable { 99 | //ARRANGE// 100 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 101 | final MainPageSteps mainPageSteps = new MainPageSteps(); 102 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 103 | final ShoppingLoggedUserSteps shoppingLoggedUserSteps = new ShoppingLoggedUserSteps(new ContextInjection()); 104 | 105 | excelEnvironment.saveTestResultsXLSX(40); 106 | 107 | List> orderDetails = Arrays.asList 108 | ( 109 | Arrays.asList("Quantity", "Size", "Colour"), 110 | Arrays.asList("2", "S", "Black") 111 | ); 112 | DataTable orderDetailsDataTable = DataTable.create(orderDetails); 113 | 114 | List> paymentDetails = Arrays.asList 115 | ( 116 | Collections.singletonList("Payment Method"), 117 | Collections.singletonList("Pay by bank wire") 118 | ); 119 | DataTable paymentDetailsDataTable = DataTable.create(paymentDetails); 120 | 121 | //ACT// 122 | mainPageSteps.iOpenHomePage(); 123 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 124 | mainPageSteps.iAmLoggedAsCustomerUsingPassword("thor.odinson@example.com", "12345"); 125 | registrationPageSteps.iCanSeeWelcomeMessage(); 126 | mainPageSteps.iAmOnMyAccountDetailsPage(); 127 | shoppingLoggedUserSteps.iClickOnButtonFromSubMenu("Women"); 128 | shoppingLoggedUserSteps.iClickOnFollowingProduct("Blouse"); 129 | shoppingLoggedUserSteps.iChooseFollowingDetailsOfMyOrder(orderDetailsDataTable); 130 | shoppingLoggedUserSteps.iClickOnAddToCartButton(); 131 | shoppingLoggedUserSteps.iCanSeeModalWhereIAmAbleToSeeDetailedDataAboutMyPurchase(); 132 | shoppingLoggedUserSteps.iClickOnProceedToCheckoutButtonFromModal(); 133 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Your shopping cart"); 134 | shoppingLoggedUserSteps.iClickOnProceedToCheckoutButtonFromShoppingCart(); 135 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Addresses"); 136 | shoppingLoggedUserSteps.iWriteCommentAboutMyOrder(); 137 | shoppingLoggedUserSteps.iClickOnProceedToCheckoutButtonFromShoppingCart(); 138 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Shipping"); 139 | shoppingLoggedUserSteps.iChooseShippingOption("My carrier"); 140 | shoppingLoggedUserSteps.iClickOnTermsOfServiceCheckbox(); 141 | shoppingLoggedUserSteps.iClickOnProceedToCheckoutButtonFromShoppingCart(); 142 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Your payment method"); 143 | shoppingLoggedUserSteps.iChoosePaymentMethod(paymentDetailsDataTable); 144 | shoppingLoggedUserSteps.iClickOnIConfirmMyOrderButton(); 145 | 146 | //ASSERT 147 | shoppingLoggedUserSteps.iCanSeeShoppingCartFormWithValidInformation("Order confirmation"); 148 | } 149 | } -------------------------------------------------------------------------------- /src/test/java/com/buildSettings/TestCommons.java: -------------------------------------------------------------------------------- 1 | package com.buildSettings; 2 | 3 | import com.DriverFactory; 4 | import com.google.common.collect.ImmutableMap; 5 | import org.openqa.selenium.NoSuchElementException; 6 | import org.openqa.selenium.*; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | import org.openqa.selenium.remote.Command; 9 | import org.openqa.selenium.remote.CommandExecutor; 10 | import org.openqa.selenium.support.ui.ExpectedConditions; 11 | import org.openqa.selenium.support.ui.Select; 12 | import org.openqa.selenium.support.ui.WebDriverWait; 13 | 14 | import java.io.IOException; 15 | import java.security.SecureRandom; 16 | import java.util.*; 17 | 18 | /** 19 | * Test_Automation-automationpractice 20 | * 21 | * @author kamil.nowocin 22 | **/ 23 | 24 | public class TestCommons extends TestEnvironment { 25 | 26 | /** 27 | * WAIT METHODS 28 | **/ 29 | public void waitForElementToBeClickable(WebElement webElement) { 30 | try { 31 | WebDriverWait wait = new WebDriverWait(DriverFactory.getDriver(), Timeouts.CLICK_TIMEOUT.value); 32 | wait.until(ExpectedConditions.elementToBeClickable(webElement)); 33 | } catch (ElementNotInteractableException e) { 34 | logger.error(String.format("Couldn't click on element \"%S\"!", webElement)); 35 | } 36 | } 37 | 38 | public void waitForElementToHaveAttribute(WebElement webElement, String attribute, String value) { 39 | try { 40 | WebDriverWait wait = new WebDriverWait(DriverFactory.getDriver(), Timeouts.ATTRIBUTE_TIMEOUT.value); 41 | wait.until(ExpectedConditions.attributeContains(webElement, attribute, value)); 42 | } catch (NoSuchElementException e) { 43 | logger.error(String.format("Couldn't find attribute \"%S\" on element \"%S\"!", attribute, webElement)); 44 | } 45 | } 46 | 47 | public void waitForElementToBeVisible(WebElement webElement) { 48 | try { 49 | WebDriverWait wait = new WebDriverWait(DriverFactory.getDriver(), Timeouts.VISIBLE_TIMEOUT.value); 50 | wait.until(ExpectedConditions.visibilityOf(webElement)); 51 | } catch (ElementNotVisibleException e) { 52 | logger.error(String.format("Couldn't display element \"%S\"!", webElement)); 53 | } 54 | } 55 | 56 | public boolean isElementVisible(WebElement webElement) { 57 | try { 58 | WebDriverWait wait = new WebDriverWait(DriverFactory.getDriver(), Timeouts.VISIBLE_TIMEOUT.value); 59 | wait.until(ExpectedConditions.visibilityOf(webElement)); 60 | return true; 61 | } catch (ElementNotVisibleException e) { 62 | logger.error(String.format("Couldn't display element \"%S\"!", webElement)); 63 | return false; 64 | } 65 | } 66 | 67 | /** 68 | * SELECT METHODS 69 | **/ 70 | public void selectFromDropdownByIndex(int value, WebElement webElement) { 71 | try { 72 | Select dropdown = new Select(webElement); 73 | dropdown.selectByIndex(value); 74 | } catch (ElementNotSelectableException e) { 75 | logger.error(String.format("Couldn't select \"%S\" from element \"%S\"!", value, webElement)); 76 | } 77 | } 78 | 79 | public void selectFromDropdownByText(String textValue, WebElement webElement) { 80 | try { 81 | Select dropdown = new Select(webElement); 82 | dropdown.selectByVisibleText(textValue); 83 | } catch (ElementNotSelectableException e) { 84 | logger.error(String.format("Couldn't select \"%S\" from element \"%S\"!", textValue, webElement)); 85 | } 86 | } 87 | 88 | public void selectFromDropdownByValue(String textValue, WebElement webElement) { 89 | try { 90 | Select dropdown = new Select(webElement); 91 | dropdown.selectByValue(textValue); 92 | } catch (ElementNotSelectableException e) { 93 | logger.error(String.format("Couldn't select \"%S\" from element \"%S\"!", textValue, webElement)); 94 | } 95 | } 96 | 97 | /** 98 | * RANDOM METHODS 99 | **/ 100 | public int getRandomIntValue(int max, int min) { 101 | Random random = new Random(); 102 | return random.nextInt((max - min) + 1) + min; 103 | } 104 | 105 | public String getRandomStringValue(int length) { 106 | String characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 107 | SecureRandom secureRandom = new SecureRandom(); 108 | StringBuilder stringBuilder = new StringBuilder(length); 109 | for (int i = 0; i < length; i++) 110 | stringBuilder.append(characters.charAt(secureRandom.nextInt(characters.length()))); 111 | return stringBuilder.toString(); 112 | } 113 | 114 | public String getRandomResourceBundleValue(String resourceBundle) { 115 | List resourceBundleData = Arrays.asList((resourceBundle.split("\\s*, "))); 116 | Random random = new Random(); 117 | return resourceBundleData.get(random.nextInt(resourceBundleData.size())); 118 | } 119 | 120 | /** 121 | * GENERAL METHODS 122 | **/ 123 | public static boolean isPageReady() { 124 | try { 125 | WebDriverWait wait = new WebDriverWait(DriverFactory.getDriver(), Timeouts.PAGE_LOAD_TIMEOUT.value); 126 | wait.until(webDriver -> 127 | ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete")); 128 | } catch (WebDriverException e) { 129 | logger.error(String.format("Page wasn't ready to execute tests: %s!", DriverFactory.getDriver().getCurrentUrl())); 130 | return false; 131 | } 132 | return true; 133 | } 134 | 135 | public void customClick(WebElement webElement) { 136 | waitForElementToBeClickable(webElement); 137 | try { 138 | webElement.click(); 139 | } catch (ElementNotInteractableException e) { 140 | logger.error(String.format("Couldn't click on element \"%S\"!", webElement), e); 141 | } 142 | } 143 | 144 | public void customSendKeys(WebElement webElement, String whatToSend) { 145 | waitForElementToBeVisible(webElement); 146 | try { 147 | webElement.sendKeys(whatToSend); 148 | } catch (ElementNotInteractableException e) { 149 | logger.error(String.format("Couldn't send \"%S\" on element \"%S\"!", whatToSend, webElement), e); 150 | } 151 | } 152 | 153 | public void networkThrottling(boolean enableThrottling) throws IOException { 154 | Map map = new HashMap<>(); 155 | if (enableThrottling) { 156 | map.put("offline", true); 157 | map.put("latency", 10000); 158 | map.put("download_throughput", 0); 159 | map.put("upload_throughput", 0); 160 | CommandExecutor executor = ((ChromeDriver) DriverFactory.getDriver()).getCommandExecutor(); 161 | executor.execute(new Command(((ChromeDriver) DriverFactory.getDriver()).getSessionId(), "setNetworkConditions", 162 | ImmutableMap.of("network_conditions", ImmutableMap.copyOf(map))) 163 | ); 164 | } 165 | } 166 | 167 | public void scrollWebsiteToElement(WebElement webElement) { 168 | waitForElementToBeVisible(webElement); 169 | try { 170 | JavascriptExecutor js = (JavascriptExecutor) DriverFactory.getDriver(); 171 | js.executeScript("arguments[0].scrollIntoView(true);", webElement); 172 | } catch (NoSuchElementException e) { 173 | logger.error(String.format("Couldn't scroll to element \"%S\"!", webElement), e); 174 | } 175 | } 176 | 177 | //Just for testing purpose, it shouldn't be used in development environment 178 | public void sleep(int seconds) throws InterruptedException { 179 | Thread.sleep(seconds * 1000); 180 | } 181 | } -------------------------------------------------------------------------------- /src/test/java/com/steps/CustomerServicePageSteps.java: -------------------------------------------------------------------------------- 1 | package com.steps; 2 | 3 | import com.buildSettings.ContextInjection; 4 | import com.buildSettings.TestCommons; 5 | import com.buildSettings.TestEnvironment; 6 | import com.pages.CustomerServicePage; 7 | import com.pages.MainPage; 8 | import io.cucumber.java.en.And; 9 | import io.cucumber.java.en.Given; 10 | import io.cucumber.java.en.Then; 11 | import io.cucumber.java.en.When; 12 | import io.qameta.allure.Step; 13 | import org.testng.Assert; 14 | 15 | import java.io.File; 16 | 17 | /** 18 | * Test_Automation-automationpractice 19 | * 20 | * @author kamil.nowocin 21 | **/ 22 | 23 | public class CustomerServicePageSteps extends TestEnvironment { 24 | 25 | private final MainPage mainPage = new MainPage().get(); 26 | private final TestCommons testCommons = new TestCommons(); 27 | private final CustomerServicePage customerServicePage = new CustomerServicePage().get(); 28 | 29 | @Step("I click on Contact Us button") 30 | @When("I click on Contact Us button") 31 | public void iClickOnContactUsButton() throws Throwable { 32 | testCommons.customClick(mainPage.contactUsButton); 33 | } 34 | 35 | @Step("I can see Contact Us form") 36 | @Then("I can see Contact Us form") 37 | public void iCanSeeContactUsForm() throws Throwable { 38 | Assert.assertTrue(testCommons.isElementVisible(customerServicePage.contactUsPane), 39 | String.format(ContextInjection.VIEW_ERROR, "Contact Us form")); 40 | } 41 | 42 | @Step("I am on Customer Service Contact Us page form") 43 | @Given("I am on Customer Service Contact Us page form") 44 | public void iAmOnCustomerServiceContactUsPageForm() throws Throwable { 45 | Assert.assertTrue(testCommons.isElementVisible(customerServicePage.contactUsHeader), 46 | String.format(ContextInjection.VIEW_ERROR, "Customer Service Contact Us page form")); 47 | } 48 | 49 | @Step("I choose Subject Heading *{0}*") 50 | @When("I choose Subject Heading {string}") 51 | public void iChooseSubjectHeading(String subjectHeading) throws Throwable { 52 | //ACT// 53 | testCommons.selectFromDropdownByText(subjectHeading, customerServicePage.subjectHeadingDropdown); 54 | logger.info(String.format("Chosen subject: \"%S\"", subjectHeading)); 55 | 56 | //ASSERT// 57 | Assert.assertEquals(customerServicePage.readSubjectHeading.getText().toLowerCase(), 58 | subjectHeading.toLowerCase(), ContextInjection.VALUE_ERROR); 59 | } 60 | 61 | @Step("I write an email address in contact us page") 62 | @And("I write an email address in contact us page") 63 | public void iWriteAnEmailAddressInContactUsPage() throws Throwable { 64 | //ARRANGE// 65 | final String userValidEmailAddress = mockNeat.emails().val(); 66 | 67 | //ACT// 68 | testCommons.customSendKeys(customerServicePage.emailAddressInput, userValidEmailAddress); 69 | logger.info(String.format("User valid email: \"%S\"", userValidEmailAddress)); 70 | 71 | //ASSERT// 72 | Assert.assertEquals(customerServicePage.emailAddressInput.getAttribute("value").toLowerCase(), 73 | userValidEmailAddress.toLowerCase(), ContextInjection.VALUE_ERROR); 74 | } 75 | 76 | @Step("I write an invalid email address in contact us page") 77 | @And("I write an invalid email address in contact us page") 78 | public void iWriteAnInvalidEmailAddressInContactUsPage() throws Throwable { 79 | //ARRANGE// 80 | final String userInvalidEmailAddress = testCommons.getRandomResourceBundleValue 81 | (RESOURCE_BUNDLE_INVALID_EMAILS.getString("invalidEmails")); 82 | 83 | //ACT// 84 | testCommons.customSendKeys(customerServicePage.emailAddressInput, userInvalidEmailAddress); 85 | logger.info(String.format("User invalid email: \"%S\"", userInvalidEmailAddress)); 86 | 87 | //ASSERT// 88 | Assert.assertEquals(customerServicePage.emailAddressInput.getAttribute("value").toLowerCase(), 89 | userInvalidEmailAddress.toLowerCase(), ContextInjection.VALUE_ERROR); 90 | } 91 | 92 | @Step("I write order reference") 93 | @And("I write order reference") 94 | public void iWriteOrderReference() throws Throwable { 95 | //ARRANGE// 96 | final String orderReference = testCommons.getRandomStringValue(10); 97 | 98 | //ACT// 99 | testCommons.customSendKeys(customerServicePage.orderReferenceInput, orderReference); 100 | logger.info(String.format("Order reference: \"%S\"", orderReference)); 101 | 102 | //ASSERT// 103 | Assert.assertEquals(customerServicePage.orderReferenceInput.getAttribute("value").toLowerCase(), 104 | orderReference.toLowerCase(), ContextInjection.VALUE_ERROR); 105 | } 106 | 107 | @Step("I write message") 108 | @And("I write message") 109 | public void iWriteMessage() throws Throwable { 110 | //ARRANGE// 111 | final String message = faker.chuckNorris().fact(); 112 | 113 | //ACT// 114 | testCommons.customSendKeys(customerServicePage.messageTextArea, message); 115 | logger.info(String.format("Message: \"%S\"", message)); 116 | 117 | //ASSERT// 118 | Assert.assertEquals(customerServicePage.messageTextArea.getAttribute("value").toLowerCase(), 119 | message.toLowerCase(), ContextInjection.VALUE_ERROR); 120 | } 121 | 122 | @Step("I choose file to attach") 123 | @And("I choose file to attach") 124 | public void iChooseFileToAttach() throws Throwable { 125 | //ARRANGE// 126 | final String fileName = "testPhoto.jpg"; 127 | String path = getCurrentPath() 128 | + File.separator 129 | + "src" 130 | + File.separator 131 | + "test" 132 | + File.separator 133 | + "resources" 134 | + File.separator 135 | + "files" 136 | + File.separator 137 | + "images" 138 | + File.separator; 139 | path += fileName; 140 | 141 | //ACT// 142 | customerServicePage.attachFileInput.sendKeys(path); 143 | logger.info(String.format("Uploaded file name: \"%S\"", fileName)); 144 | 145 | //ASSERT// 146 | Assert.assertEquals(customerServicePage.readFileName.getText().toLowerCase(), fileName.toLowerCase(), ContextInjection.VALUE_ERROR); 147 | } 148 | 149 | @Step("I click Send button") 150 | @Then("I click Send button") 151 | public void iClickSendButton() throws Throwable { 152 | testCommons.customClick(customerServicePage.sendButton); 153 | } 154 | 155 | @Step("I can see success message *{0}*") 156 | @And("I can see success message {string}") 157 | public void iCanSeeSuccessMessage(String successMessage) throws Throwable { 158 | Assert.assertTrue(customerServicePage.contactUsSuccessMessage.getText().toLowerCase().contains 159 | (successMessage.toLowerCase()), String.format(ContextInjection.MESSAGE_DIDNT_CONTAIN, successMessage.toUpperCase())); 160 | } 161 | 162 | @Step("I can see error message *{0}*") 163 | @And("I can see error message {string}") 164 | public void iCanSeeErrorMessage(String errorMessage) throws Throwable { 165 | Assert.assertTrue(customerServicePage.contactUsErrorMessage.getText().toLowerCase().contains 166 | (errorMessage.toLowerCase()), String.format(ContextInjection.MESSAGE_DIDNT_CONTAIN, errorMessage.toUpperCase())); 167 | } 168 | 169 | @Step("I don't choose Subject Heading") 170 | @When("I don't choose Subject Heading") 171 | public void iDonTChooseSubjectHeading() throws Throwable { 172 | } 173 | 174 | @Step("I don't write an email address") 175 | @And("I don't write an email address") 176 | public void iDonTWriteAnEmailAddress() throws Throwable { 177 | } 178 | 179 | @Step("I don't write message") 180 | @And("I don't write message") 181 | public void iDonTWriteMessage() throws Throwable { 182 | } 183 | } -------------------------------------------------------------------------------- /src/test/java/com/DriverFactory.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import com.buildSettings.TestEnvironment; 4 | import io.github.bonigarcia.wdm.WebDriverManager; 5 | import org.openqa.selenium.Platform; 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.ie.InternetExplorerDriver; 14 | import org.openqa.selenium.ie.InternetExplorerOptions; 15 | import org.openqa.selenium.opera.OperaDriver; 16 | import org.openqa.selenium.opera.OperaOptions; 17 | import org.openqa.selenium.remote.DesiredCapabilities; 18 | import org.openqa.selenium.remote.RemoteWebDriver; 19 | import org.openqa.selenium.safari.SafariDriver; 20 | import org.openqa.selenium.safari.SafariOptions; 21 | 22 | import java.net.MalformedURLException; 23 | import java.net.URL; 24 | import java.util.ArrayList; 25 | import java.util.HashMap; 26 | import java.util.List; 27 | import java.util.concurrent.TimeUnit; 28 | 29 | /** 30 | * Test_Automation-automationpractice 31 | * 32 | * @author kamil.nowocin 33 | **/ 34 | 35 | public class DriverFactory extends TestEnvironment { 36 | 37 | protected WebDriver driver; 38 | private static final List storedDrivers = new ArrayList<>(); 39 | private static final ThreadLocal drivers = new ThreadLocal<>(); 40 | 41 | public static WebDriver getDriver() { 42 | return drivers.get(); 43 | } 44 | 45 | private void addDriver(WebDriver driver) { 46 | storedDrivers.add(driver); 47 | drivers.set(driver); 48 | } 49 | 50 | public static String getTestsExecutor() { 51 | String getTestsExecutor = System.getProperty("tests.executor"); 52 | if (getTestsExecutor == null) { 53 | getTestsExecutor = System.getenv("tests.executor"); 54 | if (getTestsExecutor == null) { 55 | getTestsExecutor = DEFAULT_TESTS_EXECUTOR; 56 | } 57 | } 58 | return getTestsExecutor; 59 | } 60 | 61 | private String getRemoteBrowserName() { 62 | String getRemoteBrowserName = System.getProperty("remote.browser"); 63 | if (getRemoteBrowserName == null) { 64 | getRemoteBrowserName = System.getenv("remote.browser"); 65 | if (getRemoteBrowserName == null) { 66 | getRemoteBrowserName = DEFAULT_REMOTE_BROWSER; 67 | } 68 | } 69 | return getRemoteBrowserName; 70 | } 71 | 72 | private RemoteWebDriver remoteWebDriver(String remoteWebDriverURL, DesiredCapabilities desiredCapabilities) { 73 | try { 74 | driver = new RemoteWebDriver(new URL(remoteWebDriverURL), desiredCapabilities); 75 | } catch (MalformedURLException e) { 76 | logger.error("Failed to launch remote driver!", e); 77 | } 78 | return (RemoteWebDriver) driver; 79 | } 80 | 81 | protected void startBrowser() { 82 | displayWebDriverManagerBrowsersVersions(false); 83 | switch (getTestsExecutor().toLowerCase()) { 84 | case "chrome": 85 | WebDriverManager.chromedriver().setup(); 86 | ChromeOptions chromeOptions = new ChromeOptions(); 87 | addDriver(driver = new ChromeDriver(chromeOptions)); 88 | break; 89 | case "firefox": 90 | WebDriverManager.firefoxdriver().setup(); 91 | FirefoxOptions firefoxOptions = new FirefoxOptions(); 92 | addDriver(driver = new FirefoxDriver(firefoxOptions)); 93 | break; 94 | case "opera": 95 | WebDriverManager.operadriver().setup(); 96 | OperaOptions operaOptions = new OperaOptions(); 97 | addDriver(driver = new OperaDriver(operaOptions)); 98 | break; 99 | case "edge": 100 | WebDriverManager.edgedriver().setup(); 101 | EdgeOptions edgeOptions = new EdgeOptions(); 102 | addDriver(driver = new EdgeDriver(edgeOptions)); 103 | break; 104 | case "ie": 105 | WebDriverManager.iedriver().setup(); 106 | InternetExplorerOptions internetExplorerOptions = new InternetExplorerOptions(); 107 | addDriver(driver = new InternetExplorerDriver(internetExplorerOptions)); 108 | break; 109 | case "safari": 110 | SafariOptions safariOptions = new SafariOptions(); 111 | addDriver(driver = new SafariDriver(safariOptions)); 112 | break; 113 | case "grid": 114 | addDriver(driver = remoteWebDriver(SELENIUM_GRID_URL, getCapabilityForRemoteBrowser(getRemoteBrowserName().toLowerCase()))); 115 | break; 116 | case "browserstack": 117 | DesiredCapabilities BrowserStackDesiredCapabilities = new DesiredCapabilities(); 118 | if (getRemoteBrowserName().toLowerCase().equals("ie")) { 119 | BrowserStackDesiredCapabilities.setCapability("browserName", "IE"); 120 | BrowserStackDesiredCapabilities.setCapability("browserVersion", "11.0"); 121 | } else if (getRemoteBrowserName().toLowerCase().equals("edge")) { 122 | BrowserStackDesiredCapabilities.setCapability("browserName", "Edge"); 123 | BrowserStackDesiredCapabilities.setCapability("browserVersion", "latest"); 124 | } else if (getRemoteBrowserName().toLowerCase().equals("firefox")) { 125 | BrowserStackDesiredCapabilities.setCapability("browser", "Firefox"); 126 | BrowserStackDesiredCapabilities.setCapability("browserVersion", "latest"); 127 | } else if (getRemoteBrowserName().toLowerCase().equals("chrome")) { 128 | BrowserStackDesiredCapabilities.setCapability("browserName", "Chrome"); 129 | BrowserStackDesiredCapabilities.setCapability("browserVersion", "latest"); 130 | } else { 131 | BrowserStackDesiredCapabilities.setCapability("browserName", DEFAULT_REMOTE_BROWSER); 132 | BrowserStackDesiredCapabilities.setCapability("browserVersion", "latest"); 133 | } 134 | HashMap BrowserStackOptions = new HashMap<>(); 135 | BrowserStackOptions.put("os", "Windows"); 136 | BrowserStackOptions.put("osVersion", "10"); 137 | BrowserStackOptions.put("resolution", "1920x1080"); 138 | BrowserStackOptions.put("projectName", "Automationpractice.com"); 139 | BrowserStackOptions.put("local", "true"); 140 | BrowserStackOptions.put("networkLogs", "true"); 141 | BrowserStackOptions.put("seleniumVersion", "3.141.59"); 142 | BrowserStackDesiredCapabilities.setCapability("bstack:options", BrowserStackOptions); 143 | //https://automate.browserstack.com/dashboard/v2 <- USER_NAME AND ACCESS_KEY 144 | //https://www.browserstack.com/automate/capabilities <- GENERATE YOUR OWN CAPABILITIES 145 | //-Dbrowserstack.hostURL=https://$USER_NAME:$ACCESS_KEY@hub-cloud.browserstack.com/wd/hub <- BROWSERSTACK_HOST_URL 146 | addDriver(driver = remoteWebDriver(BROWSERSTACK_HOST_URL, BrowserStackDesiredCapabilities)); 147 | break; 148 | default: 149 | throw new IllegalStateException("This browser isn't supported yet! Sorry..."); 150 | } 151 | //NOT THE BEST PRACTICE TO MIX IMPLICITLY WITH EXPLICITLY WAIT 152 | //getDriver().manage().timeouts().implicitlyWait(Timeouts.FIND_ELEMENT_TIMEOUT.value, TimeUnit.SECONDS); 153 | getDriver().manage().timeouts().pageLoadTimeout(Timeouts.PAGE_LOAD_TIMEOUT.value, TimeUnit.SECONDS); 154 | getDriver().manage().timeouts().setScriptTimeout(Timeouts.SCRIPT_TIMEOUT.value, TimeUnit.SECONDS); 155 | getDriver().manage().deleteAllCookies(); 156 | getDriver().manage().window().maximize(); 157 | } 158 | 159 | public DesiredCapabilities getCapabilityForRemoteBrowser(String browserName) { 160 | DesiredCapabilities desiredCapabilities; 161 | switch (browserName.toLowerCase()) { 162 | case "chrome": 163 | WebDriverManager.chromedriver().setup(); 164 | desiredCapabilities = DesiredCapabilities.chrome(); 165 | desiredCapabilities.setBrowserName("chrome"); 166 | desiredCapabilities.setPlatform(Platform.MAC); 167 | return DesiredCapabilities.chrome(); 168 | case "firefox": 169 | WebDriverManager.firefoxdriver().setup(); 170 | desiredCapabilities = DesiredCapabilities.firefox(); 171 | desiredCapabilities.setBrowserName("firefox"); 172 | desiredCapabilities.setPlatform(Platform.MAC); 173 | return DesiredCapabilities.firefox(); 174 | default: 175 | throw new IllegalStateException("This browser isn't supported yet. Sorry..."); 176 | } 177 | } 178 | 179 | protected void destroyDriver() { 180 | for (WebDriver driver : storedDrivers) { 181 | if (driver != null) { 182 | driver.quit(); 183 | } 184 | } 185 | } 186 | } -------------------------------------------------------------------------------- /src/test/java/com/buildSettings/TestEnvironment.java: -------------------------------------------------------------------------------- 1 | package com.buildSettings; 2 | 3 | import com.DriverFactory; 4 | import com.buildListeners.TestNGListener; 5 | import com.github.javafaker.Faker; 6 | import io.cucumber.java.Scenario; 7 | import io.github.bonigarcia.wdm.WebDriverManager; 8 | import io.qameta.allure.Attachment; 9 | import net.andreinc.mockneat.MockNeat; 10 | import org.apache.commons.io.FileUtils; 11 | import org.json.JSONObject; 12 | import org.openqa.selenium.OutputType; 13 | import org.openqa.selenium.TakesScreenshot; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | import org.testng.ITestResult; 17 | 18 | import java.io.File; 19 | import java.io.FileOutputStream; 20 | import java.io.FileWriter; 21 | import java.io.IOException; 22 | import java.nio.charset.StandardCharsets; 23 | import java.nio.file.Files; 24 | import java.nio.file.Paths; 25 | import java.text.DecimalFormat; 26 | import java.text.DecimalFormatSymbols; 27 | import java.text.SimpleDateFormat; 28 | import java.time.Instant; 29 | import java.util.Date; 30 | import java.util.Locale; 31 | import java.util.Properties; 32 | import java.util.ResourceBundle; 33 | import java.util.stream.Stream; 34 | 35 | /** 36 | * Test_Automation-automationpractice 37 | * 38 | * @author kamil.nowocin 39 | **/ 40 | 41 | public class TestEnvironment { 42 | 43 | protected static Faker faker = new Faker(Locale.US); 44 | protected static MockNeat mockNeat = MockNeat.secure(); 45 | protected static Logger logger = LoggerFactory.getLogger(Logger.class); 46 | protected static final String TODAY_DATE = new SimpleDateFormat("yyyy-MM-dd HH:ss").format(new Date()); 47 | protected static final DecimalFormat DOLLAR_DECIMAL_FORMAT = new DecimalFormat("$#0.00", new DecimalFormatSymbols(Locale.US)); 48 | 49 | //BUNDLES// 50 | protected static final ResourceBundle RESOURCE_BUNDLE_INVALID_EMAILS = ResourceBundle.getBundle("invalidEmails"); 51 | protected static final ResourceBundle RESOURCE_BUNDLE_ERROR_MESSAGES = ResourceBundle.getBundle("errorValidators"); 52 | 53 | //GENERAL SETTINGS// 54 | protected static final String ANSI_RED = "\u001B[31m"; 55 | protected static final String ANSI_RESET = "\u001B[0m"; 56 | protected static final String ANSI_BLUE = "\u001b[34m"; 57 | protected static final String ANSI_GREEN = "\u001B[32m"; 58 | protected static final String EXECUTOR = "GRADLE"; 59 | public static final String HOME_URL = "http://automationpractice.com/"; 60 | 61 | //ENVIRONMENT PROPERTIES// 62 | protected static final String TRAVIS_BUILD_NUMBER = System.getProperty 63 | ("travis.buildNumber", "Build was made on localhost"); 64 | protected static final String TRAVIS_BUILD_WEB_URL = System.getProperty 65 | ("travis.buildURL", "Build was made on localhost"); 66 | protected static final String TRAVIS_BRANCH = System.getProperty 67 | ("travis.branch", "Build was made on localhost"); 68 | protected static final String OS_NAME = System.getProperty 69 | ("travis.osName", "Build was made on localhost");//DON'T KNOW HOW TO SET OS TYPE WHEN BUILD RUNS ON LOCAL MACHINE OR ONLINE 70 | protected static final String JAVA_VERSION = System.getProperty 71 | ("travis.jdkVersion", "Build was made on localhost"); 72 | protected static final String SLACK_TOKEN = System.getProperty 73 | ("travis.slack", ""); 74 | protected static final String DEFAULT_REMOTE_BROWSER = System.getProperty 75 | ("remote.browser", "chrome"); 76 | protected static final String DEFAULT_TESTS_EXECUTOR = System.getProperty 77 | ("tests.executor", "chrome"); 78 | protected static final String SELENIUM_GRID_URL = System.getProperty 79 | ("selenium.gridURL", "http://localhost:4444/wd/hub"); 80 | protected static final String BROWSERSTACK_HOST_URL = System.getProperty 81 | ("browserstack.hostURL", "https://localhost:3000"); 82 | 83 | //ENVIRONMENT METHODS// 84 | public static String getCurrentPath() { 85 | return Paths.get(".").toAbsolutePath().normalize().toString(); 86 | } 87 | 88 | protected static long getUnixTime() { 89 | return Instant.now().getEpochSecond(); 90 | } 91 | 92 | public void allureWriteProperties() { 93 | Properties properties = new Properties(); 94 | properties.setProperty("All tests were executed on:", HOME_URL); 95 | properties.setProperty("Travis build URL:", TRAVIS_BUILD_WEB_URL); 96 | properties.setProperty("Travis build Run:", TRAVIS_BUILD_NUMBER); 97 | properties.setProperty("Branch:", TRAVIS_BRANCH); 98 | properties.setProperty("Browser:", DEFAULT_TESTS_EXECUTOR); 99 | properties.setProperty("OS Name:", OS_NAME); 100 | properties.setProperty("JDK Version:", JAVA_VERSION); 101 | try { 102 | properties.store(new FileOutputStream("build/allure-results/environment.properties"), null); 103 | } catch (IOException e) { 104 | logger.error("Failed to create properties file!", e); 105 | } 106 | } 107 | 108 | public void allureWriteExecutors() { 109 | JSONObject jsonObject = new JSONObject(); 110 | jsonObject.put("name", EXECUTOR); 111 | jsonObject.put("type", EXECUTOR); 112 | jsonObject.put("buildName", String.format("Allure Report via Travis CI: %s", TRAVIS_BUILD_NUMBER)); 113 | jsonObject.put("reportUrl", TRAVIS_BUILD_WEB_URL); 114 | try { 115 | FileWriter fileWriter = new FileWriter("build/allure-results/executor.json"); 116 | fileWriter.write(jsonObject.toString()); 117 | fileWriter.flush(); 118 | } catch (IOException e) { 119 | logger.error("Failed to create json object!", e); 120 | } 121 | } 122 | 123 | @Attachment(value = "TestNG test FAIL logs", type = "text/plain") 124 | protected String allureSaveTextLog(ITestResult iTestResult) { 125 | return logBuilder(MessageBuilder.getTestDescription(iTestResult)); 126 | } 127 | 128 | @Attachment(value = "Cucumber scenario FAIL logs", type = "text/plain") 129 | protected String allureSaveTextLogCucumber(Scenario scenario) { 130 | return logBuilder(scenario.getName().toUpperCase()); 131 | } 132 | 133 | @Attachment(value = "Scenario FAIL screenshot", type = "image/png") 134 | protected byte[] allureSaveScreenshotPNG() { 135 | return ((TakesScreenshot) DriverFactory.getDriver()).getScreenshotAs(OutputType.BYTES); 136 | } 137 | 138 | protected void localSaveScreenshotPNG(Scenario scenario) throws IOException { 139 | byte[] screenshot = ((TakesScreenshot) DriverFactory.getDriver()).getScreenshotAs(OutputType.BYTES); 140 | scenario.attach(screenshot, "image/png", "SCREENSHOT"); 141 | File scrFile = ((TakesScreenshot) DriverFactory.getDriver()).getScreenshotAs(OutputType.FILE); 142 | FileUtils.copyFile(scrFile, new File(getCurrentPath() 143 | + File.separator 144 | + "screenshots" 145 | + File.separator 146 | + scenario.getName() 147 | + "-" 148 | + TODAY_DATE 149 | + ".png")); 150 | } 151 | 152 | protected String logBuilder(String fileName) { 153 | String path = getCurrentPath() 154 | + File.separator 155 | + "logs" 156 | + File.separator; 157 | path += fileName + ".log"; 158 | StringBuilder contentBuilder = new StringBuilder(); 159 | try (Stream stream = Files.lines(Paths.get(path), StandardCharsets.UTF_8)) { 160 | stream.forEach(s -> contentBuilder.append(s).append("\n")); 161 | } catch (IOException e) { 162 | logger.error("Failed to attach .log file!", e); 163 | } 164 | return contentBuilder.toString(); 165 | } 166 | 167 | protected void deleteOldLogs() { 168 | try { 169 | FileUtils.deleteDirectory(new File(getCurrentPath() 170 | + File.separator 171 | + "logs")); 172 | } catch (IOException e) { 173 | logger.error("Failed to delete logs directory!", e); 174 | } 175 | } 176 | 177 | protected void suiteResultsCleaner() { 178 | ContextInjection.passedTestsAmount = 0; 179 | ContextInjection.failedTestsAmount = 0; 180 | TestNGListener.passedTests.clear(); 181 | TestNGListener.failedTests.clear(); 182 | } 183 | 184 | protected enum Timeouts { 185 | SCRIPT_TIMEOUT(15), 186 | PAGE_LOAD_TIMEOUT(30), 187 | CLICK_TIMEOUT(15), 188 | ATTRIBUTE_TIMEOUT(15), 189 | VISIBLE_TIMEOUT(15); 190 | 191 | public final int value; 192 | 193 | Timeouts(int value) { 194 | this.value = value; 195 | } 196 | } 197 | 198 | protected void displayWebDriverManagerBrowsersVersions(Boolean showBrowserVersions) { 199 | if (showBrowserVersions) { 200 | logger.info(String.format("ChromeDriver available versions: %s", WebDriverManager.chromedriver().getDriverVersions())); 201 | logger.info(String.format("GeckoDriver available versions: %s", WebDriverManager.firefoxdriver().getDriverVersions())); 202 | logger.info(String.format("OperaDriver available versions: %s ", WebDriverManager.operadriver().getDriverVersions())); 203 | logger.info(String.format("EdgeDriver available versions: %s", WebDriverManager.edgedriver().getDriverVersions())); 204 | logger.info(String.format("IEDriver available versions: %s", WebDriverManager.iedriver().getDriverVersions())); 205 | } 206 | } 207 | } -------------------------------------------------------------------------------- /src/test/resources/features/RegistrationValidators.feature: -------------------------------------------------------------------------------- 1 | #/** 2 | #* Test_Automation-automationpractice 3 | #* 4 | #* @author kamil.nowocin 5 | #**/ 6 | 7 | @registrationValidators 8 | Feature: As a user I would like to see the error message where I made a mistake in the registration page form 9 | #--------------------------------------------------------------------------------# 10 | # [UserStory] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-444 # 11 | #--------------------------------------------------------------------------------# 12 | 13 | Background: Navigate to registration page 14 | Given I open home page 15 | And I can see automationpractice.com website 16 | When I click on Sign in button 17 | And I write an email address 18 | And I click on Create An Account button 19 | Then I can see registration page form 20 | 21 | #--------------------------------------------------------------------------------# 22 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0020 23 | @non-smoke @normal @regression 24 | Scenario:[US-444]/[1] As a user I would like to see registration error, when I don't fill first name input 25 | Given I can see registration page form 26 | When I choose gender 27 | And I write my last name 28 | And I write password 29 | And I choose date of birth 30 | And I write my address 31 | And I choose country "United States" 32 | And I write city name 33 | And I choose state 34 | And I write postal code 35 | And I write mobile phone 36 | And I write my address alias 37 | And I click on Register button 38 | Then I can see warning message about missing "first name" input 39 | 40 | #--------------------------------------------------------------------------------# 41 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0021 42 | @non-smoke @normal @regression 43 | Scenario:[US-444]/[2] As a user I would like to see registration error, when I don't fill last name input 44 | Given I can see registration page form 45 | When I choose gender 46 | And I write my first name 47 | And I write password 48 | And I choose date of birth 49 | And I write my address 50 | And I choose country "United States" 51 | And I write city name 52 | And I choose state 53 | And I write postal code 54 | And I write mobile phone 55 | And I write my address alias 56 | And I click on Register button 57 | Then I can see warning message about missing "last name" input 58 | 59 | #--------------------------------------------------------------------------------# 60 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0022 61 | @non-smoke @normal @regression 62 | Scenario:[US-444]/[3] As a user I would like to see registration error, when I don't fill email input 63 | Given I can see registration page form 64 | When I choose gender 65 | And I write my first name 66 | And I write my last name 67 | And I clear my email address 68 | And I write password 69 | And I choose date of birth 70 | And I write my address 71 | And I choose country "United States" 72 | And I write city name 73 | And I choose state 74 | And I write postal code 75 | And I write mobile phone 76 | And I write my address alias 77 | And I click on Register button 78 | Then I can see warning message about missing "email address" input 79 | 80 | #--------------------------------------------------------------------------------# 81 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0023 82 | @non-smoke @normal @regression 83 | Scenario:[US-444]/[4] As a user I would like to see registration error, when I don't fill password input 84 | Given I can see registration page form 85 | When I choose gender 86 | And I write my first name 87 | And I write my last name 88 | And I choose date of birth 89 | And I write my address 90 | And I choose country "United States" 91 | And I write city name 92 | And I choose state 93 | And I write postal code 94 | And I write mobile phone 95 | And I write my address alias 96 | And I click on Register button 97 | Then I can see warning message about missing "password" input 98 | 99 | #--------------------------------------------------------------------------------# 100 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0024 101 | @non-smoke @normal @regression 102 | Scenario:[US-444]/[5] As a user I would like to see registration error, when I don't fill address input 103 | Given I can see registration page form 104 | When I choose gender 105 | And I write my first name 106 | And I write my last name 107 | And I write password 108 | And I choose date of birth 109 | And I choose country "United States" 110 | And I write city name 111 | And I choose state 112 | And I write postal code 113 | And I write mobile phone 114 | And I write my address alias 115 | And I click on Register button 116 | Then I can see warning message about missing "address" input 117 | 118 | #--------------------------------------------------------------------------------# 119 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0025 120 | @non-smoke @normal @regression 121 | Scenario:[US-444]/[6] As a user I would like to see registration error, when I don't fill city input 122 | Given I can see registration page form 123 | When I choose gender 124 | And I write my first name 125 | And I write my last name 126 | And I write password 127 | And I choose date of birth 128 | And I write my address 129 | And I choose country "United States" 130 | And I choose state 131 | And I write postal code 132 | And I write mobile phone 133 | And I write my address alias 134 | And I click on Register button 135 | Then I can see warning message about missing "city" input 136 | 137 | #--------------------------------------------------------------------------------# 138 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0026 139 | @non-smoke @normal @regression 140 | Scenario:[US-444]/[7] As a user I would like to see registration error, when I don't fill state input 141 | Given I can see registration page form 142 | When I choose gender 143 | And I write my first name 144 | And I write my last name 145 | And I write password 146 | And I choose date of birth 147 | And I write my address 148 | And I choose country "United States" 149 | And I write city name 150 | And I write postal code 151 | And I write mobile phone 152 | And I write my address alias 153 | And I click on Register button 154 | Then I can see warning message about missing "state" input 155 | 156 | #--------------------------------------------------------------------------------# 157 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0027 158 | @non-smoke @normal @regression 159 | Scenario:[US-444]/[8] As a user I would like to see registration error, when I don't fill postal code input 160 | Given I can see registration page form 161 | When I choose gender 162 | And I write my first name 163 | And I write my last name 164 | And I write password 165 | And I choose date of birth 166 | And I write my address 167 | And I choose country "United States" 168 | And I write city name 169 | And I choose state 170 | And I write mobile phone 171 | And I write my address alias 172 | And I click on Register button 173 | Then I can see warning message about missing "postal code" input 174 | 175 | #--------------------------------------------------------------------------------# 176 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0028 177 | @non-smoke @normal @regression 178 | Scenario:[US-444]/[9] As a user I would like to see registration error, when I don't fill country input 179 | Given I can see registration page form 180 | When I choose gender 181 | And I write my first name 182 | And I write my last name 183 | And I write password 184 | And I choose date of birth 185 | And I write my address 186 | And I write city name 187 | And I choose country "-" 188 | And I write mobile phone 189 | And I write my address alias 190 | And I click on Register button 191 | Then I can see warning message about missing "country" input 192 | 193 | #--------------------------------------------------------------------------------# 194 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0029 195 | @non-smoke @normal @regression 196 | Scenario:[US-444]/[10] As a user I would like to see registration error, when I don't fill mobile phone input 197 | Given I can see registration page form 198 | When I choose gender 199 | And I write my first name 200 | And I write my last name 201 | And I write password 202 | And I choose date of birth 203 | And I write my address 204 | And I choose country "United States" 205 | And I write city name 206 | And I choose state 207 | And I write postal code 208 | And I write my address alias 209 | And I click on Register button 210 | Then I can see warning message about missing "mobile phone" input 211 | 212 | #--------------------------------------------------------------------------------# 213 | # [ZEPHYR] https://tracker.FAKE.com/jira/browse/AUTOMATION_PRACTICE-0030 214 | @non-smoke @normal @regression 215 | Scenario:[US-444]/[11] As a user I would like to see registration error, when I don't fill email alias input 216 | Given I can see registration page form 217 | When I choose gender 218 | And I write my first name 219 | And I write my last name 220 | And I write password 221 | And I choose date of birth 222 | And I write my address 223 | And I choose country "United States" 224 | And I write city name 225 | And I choose state 226 | And I write postal code 227 | And I write mobile phone 228 | And I clear my email address alias 229 | And I click on Register button 230 | Then I can see warning message about missing "email address alias" input -------------------------------------------------------------------------------- /src/test/java/com/buildLogger/SlackLogger.java: -------------------------------------------------------------------------------- 1 | package com.buildLogger; 2 | 3 | import com.buildListeners.TestNGListener; 4 | import com.buildSettings.ContextInjection; 5 | import com.buildSettings.MessageBuilder; 6 | import com.buildSettings.TestEnvironment; 7 | import com.slack.api.Slack; 8 | import com.slack.api.model.Attachment; 9 | import com.slack.api.model.block.ActionsBlock; 10 | import com.slack.api.model.block.ContextBlock; 11 | import com.slack.api.model.block.DividerBlock; 12 | import com.slack.api.model.block.SectionBlock; 13 | import com.slack.api.model.block.composition.MarkdownTextObject; 14 | import com.slack.api.model.block.composition.PlainTextObject; 15 | import com.slack.api.model.block.element.ButtonElement; 16 | import com.slack.api.model.block.element.ImageElement; 17 | import com.slack.api.webhook.Payload; 18 | import com.slack.api.webhook.WebhookResponse; 19 | import org.apache.commons.lang3.StringUtils; 20 | import org.testng.ITestContext; 21 | import org.testng.ITestListener; 22 | 23 | import java.io.IOException; 24 | import java.util.ArrayList; 25 | import java.util.Arrays; 26 | import java.util.Collections; 27 | import java.util.List; 28 | 29 | /** 30 | * Test_Automation-automationpractice 31 | * 32 | * @author kamil.nowocin 33 | **/ 34 | 35 | public class SlackLogger extends TestEnvironment implements ITestListener { 36 | 37 | private static String color; 38 | private static String testAttachmentImage; 39 | private static final String URL_LINKEDIN = "https://www.linkedin.com/in/kamil-nowocin"; 40 | //https://hooks.slack.com/services/YOUR_SLACK_TOKEN <- CORRECT SLACK WEB HOOK 41 | private static final String URL_SLACK_WEB_HOOK = "https://hooks.slack.com/services/"; 42 | private static final String URL_REPOSITORY = "https://github.com/kamil-nowocin/Test_Automation-automationpractice"; 43 | private static final String URL_REPOSITORY_IMAGES = "https://raw.githubusercontent.com/kamil-nowocin/Test_Automation-automationpractice/master/src/test/resources/files/images"; 44 | 45 | private String slackResultDetailsBuilder() { 46 | List testCaseNames = new ArrayList<>(); 47 | int i = 1; 48 | if (TestNGListener.failedTests.size() == 0) { 49 | testCaseNames.add("\n*Congratulations, all tests passed successfully*:trophy:"); 50 | } else { 51 | for (String failedTest : TestNGListener.failedTests) { 52 | testCaseNames.add(String.format("*%d) FAILED TEST CASE NAME:*\n", i)); 53 | testCaseNames.add("`"); 54 | testCaseNames.add(failedTest); 55 | testCaseNames.add("`"); 56 | testCaseNames.add("\n\n"); 57 | i++; 58 | } 59 | } 60 | return (StringUtils.join(testCaseNames, "")); 61 | } 62 | 63 | private void whichColor() { 64 | if (ContextInjection.failedTestsAmount == 0) { 65 | color = "#32CD32"; //GREEN 66 | testAttachmentImage = (String.format("%s/green_icon.png", URL_REPOSITORY_IMAGES)); 67 | } else { 68 | color = "#FF4500"; //RED 69 | testAttachmentImage = (String.format("%s/red_icon.png", URL_REPOSITORY_IMAGES)); 70 | } 71 | } 72 | 73 | public void sendTestExecutionStatusToSlack(ITestContext iTestContext) { 74 | int TOTAL_TEST_CASES = ContextInjection.failedTestsAmount + ContextInjection.passedTestsAmount; 75 | whichColor(); 76 | try { 77 | Payload slackLoggerPayload = Payload.builder() 78 | .blocks(Arrays.asList( 79 | ContextBlock.builder() 80 | .elements(Arrays.asList( 81 | MarkdownTextObject.builder() 82 | .text("Author: _*Kamil Nowocin*_") 83 | .build(), 84 | ImageElement.builder() 85 | .imageUrl((String.format("%s/linkedin_icon.png", URL_REPOSITORY_IMAGES))) 86 | .altText("test") 87 | .build(), 88 | MarkdownTextObject.builder() 89 | .text(String.format("<%s| LinkedIn>", URL_LINKEDIN)) 90 | .build())) 91 | .build(), 92 | DividerBlock.builder().build(), 93 | SectionBlock.builder().text 94 | (MarkdownTextObject.builder() 95 | .text((String.format("\nNumber of tests executed: *%d*\nRepository:" + 96 | " *<%s| Test_Automation-automationpractice>* ", TOTAL_TEST_CASES, URL_REPOSITORY))) 97 | .build()) 98 | .build(), 99 | SectionBlock.builder().fields(Arrays.asList( 100 | MarkdownTextObject.builder() 101 | .text(String.format(":large_green_square:*PASSED TESTS*\n(%d/%d)", 102 | ContextInjection.passedTestsAmount, TOTAL_TEST_CASES)) 103 | .build(), 104 | MarkdownTextObject.builder() 105 | .text(String.format(":large_red_square:*FAILED TESTS*\n(%d/%d)", 106 | ContextInjection.failedTestsAmount, TOTAL_TEST_CASES)) 107 | .build())) 108 | .build(), 109 | DividerBlock.builder().build())) 110 | .attachments(Collections.singletonList( 111 | Attachment.builder() 112 | .color(color) 113 | .blocks(Arrays.asList( 114 | SectionBlock.builder().text 115 | (MarkdownTextObject.builder() 116 | .text((String.format("Execution date: \n\n" + 117 | "*XML SUITE NAME:* %s\n*XML TESTS:* %s\n" + 118 | "*====================FAILURE DETAILS====================*\n\n%s", 119 | getUnixTime(), MessageBuilder.getXmlSuiteName(iTestContext), 120 | MessageBuilder.getXmlTestName(iTestContext), slackResultDetailsBuilder()))) 121 | .build()) 122 | .accessory 123 | (ImageElement.builder() 124 | .imageUrl(testAttachmentImage) 125 | .altText("TEST FAILED") 126 | .build()) 127 | .build(), 128 | SectionBlock.builder().text 129 | (MarkdownTextObject.builder() 130 | .text("Click for more information from Travis-CI") 131 | .build()) 132 | .accessory 133 | (ButtonElement.builder() 134 | .text(PlainTextObject.builder() 135 | .text("Travis-CI") 136 | .emoji(true) 137 | .build()) 138 | .url(TRAVIS_BUILD_WEB_URL) 139 | .style("danger") 140 | .build()) 141 | .build(), 142 | ActionsBlock.builder() 143 | .elements(Collections.singletonList( 144 | ButtonElement.builder() 145 | .text(PlainTextObject.builder() 146 | .text("Another button") 147 | .emoji(true) 148 | .build()) 149 | .url("https://www.fakeurl.pl") 150 | .style("danger") 151 | .build())) 152 | .build(), 153 | DividerBlock.builder().build(), 154 | SectionBlock.builder().text 155 | (MarkdownTextObject.builder() 156 | .text((String.format("End of test execution for: *%s* :ghost:", 157 | MessageBuilder.getXmlTestName(iTestContext)))) 158 | .build()) 159 | .build() 160 | )).build() 161 | )) 162 | .build(); 163 | WebhookResponse webhookResponse = Slack.getInstance().send(String.format("%s/%s", URL_SLACK_WEB_HOOK, SLACK_TOKEN), slackLoggerPayload); 164 | logger.info(slackLoggerResponse(webhookResponse)); 165 | } catch (IOException e) { 166 | logger.error("Unexpected Error! WebHook: " + URL_SLACK_WEB_HOOK); 167 | } 168 | } 169 | 170 | private String slackLoggerResponse(WebhookResponse webhookResponse) { 171 | if (webhookResponse.getCode() != 200) { 172 | return String.format("Slack response: %d, Additional information: %s", webhookResponse.getCode(), webhookResponse.getBody()); 173 | } 174 | return String.format("Slack response: %d", webhookResponse.getCode()); 175 | } 176 | } -------------------------------------------------------------------------------- /src/test/java/tests/WebAPP/SearchBox_Tests.java: -------------------------------------------------------------------------------- 1 | package tests.WebAPP; 2 | 3 | import com.buildListeners.TestNGListener; 4 | import com.buildSettings.ExcelEnvironment; 5 | import com.steps.MainPageSteps; 6 | import com.steps.SearchPageSteps; 7 | import com.steps.hooks.WEB_Hooks; 8 | import io.qameta.allure.*; 9 | import org.testng.annotations.Listeners; 10 | import org.testng.annotations.Test; 11 | 12 | /** 13 | * Test_Automation-automationpractice 14 | * 15 | * @author kamil.nowocin 16 | **/ 17 | 18 | @Epic("Web App Tests") 19 | @Feature("SEARCH BOX TESTS") 20 | @Listeners({TestNGListener.class}) 21 | public class SearchBox_Tests extends WEB_Hooks { 22 | 23 | @Issue("TAP-0031") 24 | @TmsLink("STORY-555") 25 | @Story("POSITIVE FLOW") 26 | @Owner("Kamil Nowocin") 27 | @Severity(SeverityLevel.CRITICAL) 28 | @Description("[US-555]/[1] As a user I would like to use search box and be able to see results of: \"T-shirts\"") 29 | @Test(description = "[US-555]/[1] I would like to use search box and be able to see results of: \"T-shirts\"", 30 | priority = 0) 31 | public void test_1() throws Throwable { 32 | //ARRANGE// 33 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 34 | final MainPageSteps mainPageSteps = new MainPageSteps(); 35 | final SearchPageSteps searchPageSteps = new SearchPageSteps(); 36 | 37 | excelEnvironment.saveTestResultsXLSX(31); 38 | 39 | //ACT// 40 | mainPageSteps.iOpenHomePage(); 41 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 42 | searchPageSteps.iSearchForPhrase("T-shirts"); 43 | searchPageSteps.iClickOnSearchIcon(); 44 | searchPageSteps.iCanSeeNumbersOfResultsEqualsTo("1"); 45 | 46 | //ASSERT// 47 | searchPageSteps.iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase("T-shirts"); 48 | } 49 | 50 | @Issue("TAP-0032") 51 | @TmsLink("STORY-555") 52 | @Story("POSITIVE FLOW") 53 | @Owner("Kamil Nowocin") 54 | @Severity(SeverityLevel.CRITICAL) 55 | @Description("[US-555]/[2] As a user I would like to use search box and be able to see results of: \"Blouse\"") 56 | @Test(description = "[US-555]/[2] I would like to use search box and be able to see results of: \"Blouse\"", 57 | priority = 0) 58 | public void test_2() throws Throwable { 59 | //ARRANGE// 60 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 61 | final MainPageSteps mainPageSteps = new MainPageSteps(); 62 | final SearchPageSteps searchPageSteps = new SearchPageSteps(); 63 | 64 | excelEnvironment.saveTestResultsXLSX(32); 65 | 66 | //ACT// 67 | mainPageSteps.iOpenHomePage(); 68 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 69 | searchPageSteps.iSearchForPhrase("Blouse"); 70 | searchPageSteps.iClickOnSearchIcon(); 71 | searchPageSteps.iCanSeeNumbersOfResultsEqualsTo("1"); 72 | 73 | //ASSERT// 74 | searchPageSteps.iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase("Blouse"); 75 | } 76 | 77 | @Issue("TAP-0033") 78 | @TmsLink("STORY-555") 79 | @Story("POSITIVE FLOW") 80 | @Owner("Kamil Nowocin") 81 | @Severity(SeverityLevel.CRITICAL) 82 | @Description("[US-555]/[3] As a user I would like to use search box and be able to see results of: \"Printed Dress\"") 83 | @Test(description = "[US-555]/[3] I would like to use search box and be able to see results of: \"Printed Dress\"", 84 | priority = 0) 85 | public void test_3() throws Throwable { 86 | //ARRANGE// 87 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 88 | final MainPageSteps mainPageSteps = new MainPageSteps(); 89 | final SearchPageSteps searchPageSteps = new SearchPageSteps(); 90 | 91 | excelEnvironment.saveTestResultsXLSX(33); 92 | 93 | //ACT// 94 | mainPageSteps.iOpenHomePage(); 95 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 96 | searchPageSteps.iSearchForPhrase("Printed Dress"); 97 | searchPageSteps.iClickOnSearchIcon(); 98 | searchPageSteps.iCanSeeNumbersOfResultsEqualsTo("5"); 99 | 100 | //ASSERT// 101 | searchPageSteps.iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase("Printed Dress"); 102 | } 103 | 104 | @Issue("TAP-0034") 105 | @TmsLink("STORY-555") 106 | @Story("NEGATIVE FLOW") 107 | @Owner("Kamil Nowocin") 108 | @Severity(SeverityLevel.CRITICAL) 109 | @Description("[US-555]/[4] As a user I would like to use search box and be able to see results of: \"!@#$%^\"") 110 | @Test(description = "[US-555]/[4] I would like to use search box and be able to see results of: \"!@#$%^\"", 111 | priority = 0) 112 | public void test_4() throws Throwable { 113 | //ARRANGE// 114 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 115 | final MainPageSteps mainPageSteps = new MainPageSteps(); 116 | final SearchPageSteps searchPageSteps = new SearchPageSteps(); 117 | 118 | excelEnvironment.saveTestResultsXLSX(34); 119 | 120 | //ACT// 121 | mainPageSteps.iOpenHomePage(); 122 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 123 | searchPageSteps.iSearchForPhrase("!@#$%^"); 124 | searchPageSteps.iClickOnSearchIcon(); 125 | searchPageSteps.iCanSeeNumbersOfResultsEqualsTo("0"); 126 | 127 | //ASSERT// 128 | searchPageSteps.iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase("!@#$%^"); 129 | } 130 | 131 | @Issue("TAP-0035") 132 | @TmsLink("STORY-555") 133 | @Story("POSITIVE FLOW") 134 | @Owner("Kamil Nowocin") 135 | @Severity(SeverityLevel.CRITICAL) 136 | @Description("[US-555]/[5] As a user I would like to use search box and be able to see results sorted by: \"Product Name: Z to A\"") 137 | @Test(description = "[US-555]/[5] I would like to use search box and be able to see results sorted by: \"Product Name: Z to A\"", 138 | priority = 0) 139 | public void test_5() throws Throwable { 140 | //ARRANGE// 141 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 142 | final MainPageSteps mainPageSteps = new MainPageSteps(); 143 | final SearchPageSteps searchPageSteps = new SearchPageSteps(); 144 | 145 | excelEnvironment.saveTestResultsXLSX(35); 146 | 147 | //ACT// 148 | mainPageSteps.iOpenHomePage(); 149 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 150 | searchPageSteps.iSearchForPhrase("Printed Dress"); 151 | searchPageSteps.iClickOnSearchIcon(); 152 | searchPageSteps.iCanSeeNumbersOfResultsEqualsTo("5"); 153 | searchPageSteps.iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase("Printed Dress"); 154 | searchPageSteps.iSelectFromDropdownSortBy("Product Name: Z to A"); 155 | 156 | //ASSERT// 157 | searchPageSteps.iCanSeeThatResultsAreCorrectlySortedBy("Product Name: Z to A"); 158 | } 159 | 160 | @Issue("TAP-0036") 161 | @TmsLink("STORY-555") 162 | @Story("POSITIVE FLOW") 163 | @Owner("Kamil Nowocin") 164 | @Severity(SeverityLevel.CRITICAL) 165 | @Description("[US-555]/[6] As a user I would like to use search box and be able to see results sorted by: \"Product Name: A to Z\"") 166 | @Test(description = "[US-555]/[6] I would like to use search box and be able to see results sorted by: \"Product Name: A to Z\"", 167 | priority = 0) 168 | public void test_6() throws Throwable { 169 | //ARRANGE// 170 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 171 | final MainPageSteps mainPageSteps = new MainPageSteps(); 172 | final SearchPageSteps searchPageSteps = new SearchPageSteps(); 173 | 174 | excelEnvironment.saveTestResultsXLSX(36); 175 | 176 | //ACT// 177 | mainPageSteps.iOpenHomePage(); 178 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 179 | searchPageSteps.iSearchForPhrase("Printed Dress"); 180 | searchPageSteps.iClickOnSearchIcon(); 181 | searchPageSteps.iCanSeeNumbersOfResultsEqualsTo("5"); 182 | searchPageSteps.iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase("Printed Dress"); 183 | searchPageSteps.iSelectFromDropdownSortBy("Product Name: A to Z"); 184 | 185 | //ASSERT// 186 | searchPageSteps.iCanSeeThatResultsAreCorrectlySortedBy("Product Name: A to Z"); 187 | } 188 | 189 | @Flaky 190 | @Issue("TAP-0037") 191 | @TmsLink("STORY-555") 192 | @Story("POSITIVE FLOW") 193 | @Owner("Kamil Nowocin") 194 | @Severity(SeverityLevel.CRITICAL) 195 | @Description("[US-555]/[7] As a user I would like to use search box and be able to see results sorted by: \"Price: Highest first\"") 196 | @Test(description = "[US-555]/[7] I would like to use search box and be able to see results sorted by: \"Price: Highest first\"", 197 | priority = 0) 198 | public void test_7() throws Throwable { 199 | //ARRANGE// 200 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 201 | final MainPageSteps mainPageSteps = new MainPageSteps(); 202 | final SearchPageSteps searchPageSteps = new SearchPageSteps(); 203 | 204 | excelEnvironment.saveTestResultsXLSX(37); 205 | 206 | //ACT// 207 | mainPageSteps.iOpenHomePage(); 208 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 209 | searchPageSteps.iSearchForPhrase("Printed Dress"); 210 | searchPageSteps.iClickOnSearchIcon(); 211 | searchPageSteps.iCanSeeNumbersOfResultsEqualsTo("5"); 212 | searchPageSteps.iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase("Printed Dress"); 213 | searchPageSteps.iSelectFromDropdownSortBy("Price: Highest first"); 214 | 215 | //ASSERT// 216 | searchPageSteps.iCanSeeThatResultsAreCorrectlySortedBy("Price: Highest first"); 217 | } 218 | 219 | @Flaky 220 | @Issue("TAP-0038") 221 | @TmsLink("STORY-555") 222 | @Story("POSITIVE FLOW") 223 | @Owner("Kamil Nowocin") 224 | @Severity(SeverityLevel.CRITICAL) 225 | @Description("[US-555]/[8] As a user I would like to use search box and be able to see results sorted by: \"Price: Lowest first\"") 226 | @Test(description = "[US-555]/[8] I would like to use search box and be able to see results sorted by: \"Price: Lowest first\"", 227 | priority = 0) 228 | public void test_8() throws Throwable { 229 | //ARRANGE// 230 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 231 | final MainPageSteps mainPageSteps = new MainPageSteps(); 232 | final SearchPageSteps searchPageSteps = new SearchPageSteps(); 233 | 234 | excelEnvironment.saveTestResultsXLSX(38); 235 | 236 | //ACT// 237 | mainPageSteps.iOpenHomePage(); 238 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 239 | searchPageSteps.iSearchForPhrase("Printed Dress"); 240 | searchPageSteps.iClickOnSearchIcon(); 241 | searchPageSteps.iCanSeeNumbersOfResultsEqualsTo("5"); 242 | searchPageSteps.iCanSeeThatEveryResultsWhichHaveBeenFoundContainsPhrase("Printed Dress"); 243 | searchPageSteps.iSelectFromDropdownSortBy("Price: Lowest first"); 244 | 245 | //ASSERT// 246 | searchPageSteps.iCanSeeThatResultsAreCorrectlySortedBy("Price: Lowest first"); 247 | } 248 | } -------------------------------------------------------------------------------- /src/test/java/tests/WebAPP/Registration_Tests.java: -------------------------------------------------------------------------------- 1 | package tests.WebAPP; 2 | 3 | import com.buildListeners.TestNGListener; 4 | import com.buildSettings.ContextInjection; 5 | import com.buildSettings.ExcelEnvironment; 6 | import com.steps.MainPageSteps; 7 | import com.steps.RegistrationPageSteps; 8 | import com.steps.hooks.WEB_Hooks; 9 | import io.cucumber.datatable.DataTable; 10 | import io.qameta.allure.*; 11 | import org.testng.annotations.Listeners; 12 | import org.testng.annotations.Test; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | /** 18 | * Test_Automation-automationpractice 19 | * 20 | * @author kamil.nowocin 21 | **/ 22 | 23 | @Epic("Web App Tests") 24 | @Feature("REGISTRATION TESTS") 25 | @Listeners({TestNGListener.class}) 26 | public class Registration_Tests extends WEB_Hooks { 27 | 28 | @Issue("TAP-0013") 29 | @TmsLink("STORY-333") 30 | @Story("POSITIVE FLOW") 31 | @Owner("Kamil Nowocin") 32 | @Severity(SeverityLevel.CRITICAL) 33 | @Description("[US-333]/[1] As a user I check availability of registration page form") 34 | @Test(description = "[US-333]/[1] I check availability of registration page form", 35 | priority = 0) 36 | public void test_1() throws Throwable { 37 | //ARRANGE// 38 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 39 | final MainPageSteps mainPageSteps = new MainPageSteps(); 40 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 41 | 42 | excelEnvironment.saveTestResultsXLSX(13); 43 | 44 | //ACT// 45 | mainPageSteps.iOpenHomePage(); 46 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 47 | registrationPageSteps.iClickOnSignInButton(); 48 | registrationPageSteps.iCanSeeRegistrationPageForm(); 49 | registrationPageSteps.iWriteAnEmailAddress(); 50 | registrationPageSteps.iClickOnCreateAnAccountButton(); 51 | 52 | //ASSERT// 53 | registrationPageSteps.iCanSeeAccountCreationPageForm(); 54 | } 55 | 56 | @Issue("TAP-0014") 57 | @TmsLink("STORY-333") 58 | @Story("POSITIVE FLOW") 59 | @Owner("Kamil Nowocin") 60 | @Severity(SeverityLevel.CRITICAL) 61 | @Description("[US-333]/[2] As a user I can create an account by filling up all fields") 62 | @Test(description = "[US-333]/[2] I can create an account by filling up all fields", 63 | priority = 1, dependsOnMethods = {"test_1"}) 64 | public void test_2() throws Throwable { 65 | //ARRANGE// 66 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 67 | final MainPageSteps mainPageSteps = new MainPageSteps(); 68 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 69 | 70 | excelEnvironment.saveTestResultsXLSX(14); 71 | 72 | //ACT// 73 | mainPageSteps.iOpenHomePage(); 74 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 75 | registrationPageSteps.iClickOnSignInButton(); 76 | registrationPageSteps.iCanSeeRegistrationPageForm(); 77 | registrationPageSteps.iWriteAnEmailAddress(); 78 | registrationPageSteps.iClickOnCreateAnAccountButton(); 79 | registrationPageSteps.iChooseGender(); 80 | registrationPageSteps.iWriteMyFirstName(); 81 | registrationPageSteps.iWriteMyLastName(); 82 | registrationPageSteps.iCheckIfEmailIsAlreadyWrittenAndValid(); 83 | registrationPageSteps.iWritePassword(); 84 | registrationPageSteps.iChooseDateOfBirth(); 85 | registrationPageSteps.iSignInToReceiveNewsletterAndSpecialOffers(); 86 | registrationPageSteps.iCheckIfMyFirstLastNameAreAlreadyWrittenAndAreCorrect(); 87 | registrationPageSteps.iWriteCompanyName(); 88 | registrationPageSteps.iWriteMyAddresses(); 89 | registrationPageSteps.iChooseCountry("United States"); 90 | registrationPageSteps.iWriteCityName(); 91 | registrationPageSteps.iChooseState(); 92 | registrationPageSteps.iWritePostalCode(); 93 | registrationPageSteps.iWriteAdditionalInformation(); 94 | registrationPageSteps.iWriteHomePhone(); 95 | registrationPageSteps.iWriteMobilePhone(); 96 | registrationPageSteps.iWriteMyAddressAlias(); 97 | registrationPageSteps.iClickOnRegisterButton(); 98 | 99 | //ASSERT// 100 | registrationPageSteps.iCanSeeWelcomeMessage(); 101 | } 102 | 103 | @Issue("TAP-0015") 104 | @TmsLink("STORY-333") 105 | @Story("POSITIVE FLOW") 106 | @Owner("Kamil Nowocin") 107 | @Severity(SeverityLevel.CRITICAL) 108 | @Description("[US-333]/[3] As a user I can create an account by filling up only required fields") 109 | @Test(description = "[US-333]/[3] I can create an account by filling up only required fields", 110 | priority = 1, dependsOnMethods = {"test_1"}) 111 | public void test_3() throws Throwable { 112 | //ARRANGE// 113 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 114 | final MainPageSteps mainPageSteps = new MainPageSteps(); 115 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 116 | 117 | excelEnvironment.saveTestResultsXLSX(15); 118 | 119 | //ACT// 120 | mainPageSteps.iOpenHomePage(); 121 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 122 | registrationPageSteps.iClickOnSignInButton(); 123 | registrationPageSteps.iCanSeeRegistrationPageForm(); 124 | registrationPageSteps.iWriteAnEmailAddress(); 125 | registrationPageSteps.iClickOnCreateAnAccountButton(); 126 | registrationPageSteps.iWriteMyFirstName(); 127 | registrationPageSteps.iWriteMyLastName(); 128 | registrationPageSteps.iCheckIfEmailIsAlreadyWrittenAndValid(); 129 | registrationPageSteps.iWritePassword(); 130 | registrationPageSteps.iCheckIfMyFirstLastNameAreAlreadyWrittenAndAreCorrect(); 131 | registrationPageSteps.iWriteMyAddresses(); 132 | registrationPageSteps.iChooseCountry("United States"); 133 | registrationPageSteps.iWriteCityName(); 134 | registrationPageSteps.iChooseState(); 135 | registrationPageSteps.iWritePostalCode(); 136 | registrationPageSteps.iWriteAdditionalInformation(); 137 | registrationPageSteps.iWriteMobilePhone(); 138 | registrationPageSteps.iWriteMyAddressAlias(); 139 | registrationPageSteps.iClickOnRegisterButton(); 140 | 141 | //ASSERT// 142 | registrationPageSteps.iCanSeeWelcomeMessage(); 143 | } 144 | 145 | @Issue("TAP-0016") 146 | @TmsLink("STORY-333") 147 | @Story("NEGATIVE FLOW") 148 | @Owner("Kamil Nowocin") 149 | @Severity(SeverityLevel.NORMAL) 150 | @Description("US-333]/[4] As a user I can't create an account without filling up fields") 151 | @Test(description = "US-333]/[4] I can't create an account without filling up fields", 152 | priority = 1, dependsOnMethods = {"test_1"}) 153 | public void test_4() throws Throwable { 154 | //ARRANGE// 155 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 156 | final MainPageSteps mainPageSteps = new MainPageSteps(); 157 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 158 | 159 | excelEnvironment.saveTestResultsXLSX(16); 160 | 161 | //ACT// 162 | mainPageSteps.iOpenHomePage(); 163 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 164 | registrationPageSteps.iClickOnSignInButton(); 165 | registrationPageSteps.iCanSeeRegistrationPageForm(); 166 | registrationPageSteps.iWriteAnEmailAddress(); 167 | registrationPageSteps.iClickOnCreateAnAccountButton(); 168 | registrationPageSteps.iClickOnRegisterButton(); 169 | 170 | //ASSERT// 171 | registrationPageSteps.iCanSeeRegistrationError(); 172 | } 173 | 174 | @Issue("TAP-0017") 175 | @TmsLink("STORY-333") 176 | @Story("NEGATIVE FLOW") 177 | @Owner("Kamil Nowocin") 178 | @Severity(SeverityLevel.NORMAL) 179 | @Description("[US-333]/[5] As a user I can't create an account, when one of required fields is missing") 180 | @Test(description = "[US-333]/[5] I can't create an account, when one of required fields is missing", 181 | priority = 1, dependsOnMethods = {"test_1"}) 182 | public void test_5() throws Throwable { 183 | //ARRANGE// 184 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 185 | final MainPageSteps mainPageSteps = new MainPageSteps(); 186 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 187 | 188 | excelEnvironment.saveTestResultsXLSX(17); 189 | 190 | List> registrationDetails = Arrays.asList 191 | ( 192 | Arrays.asList("First Name", "Last Name", "Password", "Address", "City", "State", "Postal Code", "Country", "Mobile Phone"), 193 | Arrays.asList("Thor", "Odinson", "#Passwd123", "", "City", "Alaska", "99503", "United States", "700-800-900") 194 | ); 195 | DataTable registrationDetailsDataTable = DataTable.create(registrationDetails); 196 | 197 | //ACT// 198 | mainPageSteps.iOpenHomePage(); 199 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 200 | registrationPageSteps.iClickOnSignInButton(); 201 | registrationPageSteps.iCanSeeRegistrationPageForm(); 202 | registrationPageSteps.iWriteAnEmailAddress(); 203 | registrationPageSteps.iClickOnCreateAnAccountButton(); 204 | registrationPageSteps.iWriteFollowingDataToRegistrationForm(registrationDetailsDataTable); 205 | registrationPageSteps.iCheckIfEmailIsAlreadyWrittenAndValid(); 206 | registrationPageSteps.iCheckIfMyFirstLastNameAreAlreadyWrittenAndAreCorrect(); 207 | registrationPageSteps.iWriteMyAddressAlias(); 208 | registrationPageSteps.iClickOnRegisterButton(); 209 | 210 | //ASSERT// 211 | registrationPageSteps.iCanSeeWarningMessageAboutMissingInput("one element"); 212 | } 213 | 214 | @Issue("TAP-0018") 215 | @TmsLink("STORY-333") 216 | @Story("NEGATIVE FLOW") 217 | @Owner("Kamil Nowocin") 218 | @Severity(SeverityLevel.CRITICAL) 219 | @Description("[US-333]/[6] As a user I can't create an account, when email is already in database") 220 | @Test(description = "[US-333]/[6] I can't create an account, when email is already in database", 221 | priority = 1, dependsOnMethods = {"test_1"}) 222 | public void test_6() throws Throwable { 223 | //ARRANGE// 224 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 225 | final MainPageSteps mainPageSteps = new MainPageSteps(); 226 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 227 | 228 | excelEnvironment.saveTestResultsXLSX(18); 229 | 230 | //ACT// 231 | mainPageSteps.iOpenHomePage(); 232 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 233 | registrationPageSteps.iClickOnSignInButton(); 234 | registrationPageSteps.iCanSeeRegistrationPageForm(); 235 | registrationPageSteps.iWriteAnEmailAddressWhichIsAlreadyInDatabase(); 236 | registrationPageSteps.iClickOnCreateAnAccountButton(); 237 | 238 | //ASSERT// 239 | registrationPageSteps.iCanSeeRegistrationError(); 240 | } 241 | 242 | @Issue("TAP-0019") 243 | @TmsLink("STORY-333") 244 | @Story("NEGATIVE FLOW") 245 | @Owner("Kamil Nowocin") 246 | @Severity(SeverityLevel.CRITICAL) 247 | @Description("[US-333]/[7] As a user I can't create an account, when email has wrong format") 248 | @Test(description = "[US-333]/[7] I can't create an account, when email has wrong format", 249 | priority = 1, dependsOnMethods = {"test_1"}) 250 | public void test_7() throws Throwable { 251 | //ARRANGE// 252 | ExcelEnvironment excelEnvironment = new ExcelEnvironment(); 253 | final MainPageSteps mainPageSteps = new MainPageSteps(); 254 | final RegistrationPageSteps registrationPageSteps = new RegistrationPageSteps(new ContextInjection()); 255 | 256 | excelEnvironment.saveTestResultsXLSX(19); 257 | 258 | //ACT// 259 | mainPageSteps.iOpenHomePage(); 260 | mainPageSteps.iCanSeeAutomationpracticeComWebsite(); 261 | registrationPageSteps.iClickOnSignInButton(); 262 | registrationPageSteps.iCanSeeRegistrationPageForm(); 263 | registrationPageSteps.iWriteAnInvalidEmailAddress(); 264 | registrationPageSteps.iClickOnCreateAnAccountButton(); 265 | 266 | //ASSERT// 267 | registrationPageSteps.iCanSeeRegistrationError(); 268 | } 269 | } --------------------------------------------------------------------------------