commit 807afea5868d1a98be40636825b22b852efc2a39 Author: hmalik144 Date: Tue Jan 19 14:03:37 2021 +0000 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..744289d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Project exclude paths +/target/ \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..5c98b42 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..645f4a0 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..63bf2a7 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d24ea8e --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Automation-Test-Framework.iml b/Automation-Test-Framework.iml new file mode 100644 index 0000000..78b2cc5 --- /dev/null +++ b/Automation-Test-Framework.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4acae59 --- /dev/null +++ b/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + + org.example + Automation-Test-Framework + 1.0-SNAPSHOT + + + 1.4.0 + 6.8.1 + 1.7 + 1.7 + + + + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + + + io.cucumber + cucumber-java + ${cucumber.version} + test + + + + io.cucumber + cucumber-junit + ${cucumber.version} + test + + + + org.junit.jupiter + junit-jupiter-params + 5.0.0 + + + + org.seleniumhq.selenium + selenium-java + 3.141.59 + + + io.cucumber + cucumber-java + 6.8.1 + compile + + + junit + junit + 4.12 + compile + + + io.cucumber + cucumber-junit + 6.8.1 + compile + + + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + + compile + + compile + + + + + test-compile + + test-compile + + + + + + + + \ No newline at end of file diff --git a/src/main/kotlin/HelloWorld.kt b/src/main/kotlin/HelloWorld.kt new file mode 100644 index 0000000..caea6f6 --- /dev/null +++ b/src/main/kotlin/HelloWorld.kt @@ -0,0 +1,3 @@ +public fun main(args: Array){ + print("Hello World!") +} \ No newline at end of file diff --git a/src/test/kotlin/constants/Drivers.kt b/src/test/kotlin/constants/Drivers.kt new file mode 100644 index 0000000..9bac21e --- /dev/null +++ b/src/test/kotlin/constants/Drivers.kt @@ -0,0 +1,8 @@ +package constants + +enum class Drivers( + val driverProperty: String, + val driverFileName: String +){ + Chrome("webdriver.chrome.driver", "chromedriver.exe") +} \ No newline at end of file diff --git a/src/test/kotlin/constants/Gender.kt b/src/test/kotlin/constants/Gender.kt new file mode 100644 index 0000000..9cc870d --- /dev/null +++ b/src/test/kotlin/constants/Gender.kt @@ -0,0 +1,7 @@ +package constants + +enum class Gender{ + Male, + Female, + Other +} \ No newline at end of file diff --git a/src/test/kotlin/constants/WebDriverConstans.kt b/src/test/kotlin/constants/WebDriverConstans.kt new file mode 100644 index 0000000..6616a72 --- /dev/null +++ b/src/test/kotlin/constants/WebDriverConstans.kt @@ -0,0 +1,3 @@ +package constants + +const val TIMEOUT_DURATION = 30L \ No newline at end of file diff --git a/src/test/kotlin/pages/FormPageFactory.kt b/src/test/kotlin/pages/FormPageFactory.kt new file mode 100644 index 0000000..a63811f --- /dev/null +++ b/src/test/kotlin/pages/FormPageFactory.kt @@ -0,0 +1,63 @@ +package pages + +import org.openqa.selenium.WebDriver +import org.openqa.selenium.WebElement +import org.openqa.selenium.support.FindBy +import org.openqa.selenium.support.PageFactory +import utils.scrollTo + +class FormPageFactory( + val driver: WebDriver +){ + + @FindBy(id = "firstName") + lateinit var firstName: WebElement + + @FindBy(id = "lastName") + lateinit var lastName: WebElement + + @FindBy(id = "userEmail") + lateinit var userEmail: WebElement + + @FindBy(xpath = "//*[@id=\"genterWrapper\"]/div[2]/div[1]/label") + lateinit var male: WebElement + @FindBy(xpath = "//*[@id=\"genterWrapper\"]/div[2]/div[2]/label") + lateinit var female: WebElement + @FindBy(xpath = "//*[@id=\"genterWrapper\"]/div[2]/div[3]/label") + lateinit var other: WebElement + + @FindBy(id = "userNumber") + lateinit var mobileNumber: WebElement + + @FindBy(xpath = "//*[@id=\"submit\"]") + lateinit var submit: WebElement + + init { + PageFactory.initElements(driver, this) + } + + + fun enterFirstName(first: String) = firstName.sendKeys(first) + + fun enterLastName(last: String) = lastName.sendKeys(last) + + fun enterEmailAddress(email: String) = userEmail.sendKeys(email) + + fun selectGender(gender: String) = when(gender){ + "Male"-> male.click() + "Female"-> female.click() + "Other"-> other.click() + else -> {} + } + + fun enterMobileNumber(mobile: String) = mobileNumber.sendKeys(mobile) + + fun submit(){ + + submit.apply { + scrollTo(driver) + click() + } + } + +} \ No newline at end of file diff --git a/src/test/kotlin/pages/SubmittedFormFactory.kt b/src/test/kotlin/pages/SubmittedFormFactory.kt new file mode 100644 index 0000000..2cf28c2 --- /dev/null +++ b/src/test/kotlin/pages/SubmittedFormFactory.kt @@ -0,0 +1,21 @@ +package pages + +import org.openqa.selenium.WebDriver +import org.openqa.selenium.WebElement +import org.openqa.selenium.support.FindBy +import org.openqa.selenium.support.PageFactory + +class SubmittedFormFactory( + driver: WebDriver +) { + + @FindBy(id = "example-modal-sizes-title-lg") + lateinit var tableHeader: WebElement + + init { + PageFactory.initElements(driver, this) + } + + fun checkTableIsDisplayed() = tableHeader.isDisplayed + +} \ No newline at end of file diff --git a/src/test/kotlin/stepDefinition/PracticeFormPageSteps.kt b/src/test/kotlin/stepDefinition/PracticeFormPageSteps.kt new file mode 100644 index 0000000..606c890 --- /dev/null +++ b/src/test/kotlin/stepDefinition/PracticeFormPageSteps.kt @@ -0,0 +1,77 @@ +package stepDefinition + +import constants.Drivers +import io.cucumber.java.After +import io.cucumber.java.Before +import io.cucumber.java.en.Given +import io.cucumber.java.en.Then +import io.cucumber.java.en.When +import org.openqa.selenium.WebDriver +import pages.FormPageFactory +import pages.SubmittedFormFactory +import stepDefinition.baseSteps.Driver +import stepDefinition.baseSteps.DriverSteps +import java.lang.AssertionError + + +class PracticeFormPageSteps: DriverSteps() { + + lateinit var webDriver: WebDriver + + lateinit var formPageFactory: FormPageFactory + lateinit var submittedFormFactory: SubmittedFormFactory + + @Before + fun setup(){ + webDriver = createWebDriver(Drivers.Chrome) + + formPageFactory = FormPageFactory(webDriver) + submittedFormFactory = SubmittedFormFactory(webDriver) + } + + @After + fun tearDown(){ + webDriver.finish() + } + + @Given("user is on practice form") + fun user_is_on_practice_form() { + webDriver.launchUrl("https://demoqa.com/automation-practice-form") + } + + @When("user enters first name {string} and last name {string}") + fun user_enters_first_name_and_last_name(firstName: String?, lastName: String?) { + formPageFactory.apply { + firstName?.let { enterFirstName(it) } + lastName?.let { enterLastName(it) } + } + } + + @When("user selects gender {string}") + fun user_selects_gender(gender: String?) { + gender?.let { formPageFactory.selectGender(gender) } + } + + @When("user enters email address {string}") + fun user_enters_email_address(email: String?) { + email?.let { formPageFactory.enterEmailAddress(it) } + } + + @When("user enters mobile number {string}") + fun user_enters_mobile_number(mobile: String?) { + mobile?.let { formPageFactory.enterMobileNumber(it) } + } + + @When("user clicks submit button") + fun user_clicks_submit_button() { + formPageFactory.submit() + } + + @Then("pop up is displayed") + fun pop_up_is_displayed() { + if(!submittedFormFactory.checkTableIsDisplayed()){ + throw AssertionError("Popup not displayed") + } + } + +} \ No newline at end of file diff --git a/src/test/kotlin/stepDefinition/TestRunner.kt b/src/test/kotlin/stepDefinition/TestRunner.kt new file mode 100644 index 0000000..aceb532 --- /dev/null +++ b/src/test/kotlin/stepDefinition/TestRunner.kt @@ -0,0 +1,11 @@ +package stepDefinition + +import io.cucumber.junit.Cucumber +import io.cucumber.junit.CucumberOptions +import org.junit.runner.RunWith + +@RunWith(Cucumber::class) +@CucumberOptions(features = ["src/test/resources/features"], + glue = ["stepDefinition"], + plugin = ["pretty", "json:target/reports/cucumber.json"]) +class TestRunner \ No newline at end of file diff --git a/src/test/kotlin/stepDefinition/baseSteps/Driver.kt b/src/test/kotlin/stepDefinition/baseSteps/Driver.kt new file mode 100644 index 0000000..1daac0a --- /dev/null +++ b/src/test/kotlin/stepDefinition/baseSteps/Driver.kt @@ -0,0 +1,20 @@ +package stepDefinition.baseSteps + +import constants.Drivers +import org.openqa.selenium.WebDriver +import org.openqa.selenium.chrome.ChromeDriver +import java.io.IOException + +abstract class Driver{ + + fun createChromeDriver(driver: Drivers): WebDriver { + val path = System.getProperty("user.dir") + System.setProperty(driver.driverProperty, "$path\\src\\test\\resources\\drivers\\${driver.driverFileName}") + + return when(driver){ + Drivers.Chrome -> ChromeDriver() + else -> { throw IOException("No web driver available")} + } + } + +} \ No newline at end of file diff --git a/src/test/kotlin/stepDefinition/baseSteps/DriverSteps.kt b/src/test/kotlin/stepDefinition/baseSteps/DriverSteps.kt new file mode 100644 index 0000000..72b468b --- /dev/null +++ b/src/test/kotlin/stepDefinition/baseSteps/DriverSteps.kt @@ -0,0 +1,30 @@ +package stepDefinition.baseSteps + +import constants.Drivers +import constants.TIMEOUT_DURATION +import org.openqa.selenium.WebDriver +import java.util.concurrent.TimeUnit + + +abstract class DriverSteps : Driver(){ + + fun createWebDriver(driver: Drivers): WebDriver{ + return createChromeDriver(driver).apply { + manage().timeouts().let { tO -> + tO.implicitlyWait(TIMEOUT_DURATION, TimeUnit.SECONDS) + tO.pageLoadTimeout(TIMEOUT_DURATION, TimeUnit.SECONDS) + } + } + } + + fun WebDriver.launchUrl(url: String){ + navigate().to(url) + } + + fun WebDriver.finish(){ + close() + quit() + } + +} + diff --git a/src/test/kotlin/utils/ElementUtils.kt b/src/test/kotlin/utils/ElementUtils.kt new file mode 100644 index 0000000..8d74121 --- /dev/null +++ b/src/test/kotlin/utils/ElementUtils.kt @@ -0,0 +1,14 @@ +package utils + +import org.openqa.selenium.WebDriver +import org.openqa.selenium.WebElement +import org.openqa.selenium.interactions.Actions + +/* + * Scroll down to a web element + */ +fun WebElement.scrollTo(driver: WebDriver){ + val actions = Actions(driver) + actions.moveToElement(this) + actions.perform() +} \ No newline at end of file diff --git a/src/test/resources/drivers/chromedriver.exe b/src/test/resources/drivers/chromedriver.exe new file mode 100644 index 0000000..14e61bc Binary files /dev/null and b/src/test/resources/drivers/chromedriver.exe differ diff --git a/src/test/resources/features/parctice_form.feature b/src/test/resources/features/parctice_form.feature new file mode 100644 index 0000000..27d5aab --- /dev/null +++ b/src/test/resources/features/parctice_form.feature @@ -0,0 +1,68 @@ +Feature: Feature to test the practice form + + @SmokeTest @RegressionTest + Scenario Outline: Check user can successfully submit a form with minimum mandatory valid credentials + + Given user is on practice form + When user enters first name "" and last name "" + And user selects gender "" + And user enters email address "" + And user enters mobile number "" + And user clicks submit button + Then pop up is displayed + + Examples: + | firstName | lastName | gender | emailAddress | mobileNumber | + | Harvey | Specter | Male | harvey.specter@pearson-specter.com | 2125096995 | + | Rachel | Zane | Female | rachel.zane@pearson-specter.com | 2125096965 | + + + @SmokeTest @RegressionTest + Scenario Outline: Check user can successfully submit a form with all the minimum valid credentials and 1 letter names + + Given user is on practice form + When user enters first name "" and last name "" + And user selects gender "" + And user enters email address "" + And user enters mobile number "" + And user clicks submit button + Then pop up is displayed + + Examples: + | firstName | lastName | gender | emailAddress | mobileNumber | + | i | j | Male | j@domain.com | 2125096995 | + | 2 | y | Female | y@domain.com | 2125096965 | + + + @RegressionTest + Scenario Outline: Check user cannot submit a form with if fields are empty + + Given user is on practice form + When user enters first name "" and last name "" + And user selects gender "" + And user enters email address "" + And user enters mobile number "" + And user clicks submit button + Then no pop up is displayed + + Examples: + | firstName | lastName | gender | emailAddress | mobileNumber | + | | Lastname | Male | name@domain.com | 2125096995 | + | FirstName | | Female | name@domain.com | 2125096965 | + | FirstName | Lastname | | name@domain.com | 2125096965 | + | FirstName | Lastname | Other | | 2125096965 | + | FirstName | Lastname | Other | name@domain.com | | + + @RegressionTest + Scenario Outline: Check email address shows error if incorrect email string + + Given user is on practice form + When user enters email address "" + Then email input is displaying an error + + Examples: + | emailAddress | + | namedomain.com | + | name@domain.c | + | @domain.com | +