diff --git a/pom.xml b/pom.xml index 54175bd..e48f002 100644 --- a/pom.xml +++ b/pom.xml @@ -16,10 +16,39 @@ - junit - junit - 3.8.1 + org.seleniumhq.selenium + selenium-java + 4.10.0 + + + + io.github.bonigarcia + webdrivermanager + 5.4.0 + + + + org.testng + testng + 7.8.0 test + + + + io.cucumber + cucumber-java + 7.15.0 + + + io.cucumber + cucumber-testng + 7.15.0 + + + io.cucumber + cucumber-picocontainer + 7.15.0 + diff --git a/src/main/java/wait_service/WaitService.java b/src/main/java/wait_service/WaitService.java new file mode 100644 index 0000000..64f8c00 --- /dev/null +++ b/src/main/java/wait_service/WaitService.java @@ -0,0 +1,23 @@ +package wait_service; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import java.time.Duration; + +public class WaitService { + + private WebDriverWait wait; + + public WaitService(WebDriver driver){ + this.wait = new WebDriverWait(driver, Duration.ofSeconds(10)); + } + + public WebElement waitForVisibilityByLocator(By lo){ + return wait.until(ExpectedConditions.visibilityOfElementLocated(lo)); + } + +} diff --git a/src/main/java/web_driver/WebDriverFactory.java b/src/main/java/web_driver/WebDriverFactory.java new file mode 100644 index 0000000..439d84b --- /dev/null +++ b/src/main/java/web_driver/WebDriverFactory.java @@ -0,0 +1,33 @@ +package web_driver; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.edge.EdgeDriver; +import org.openqa.selenium.edge.EdgeOptions; + +public class WebDriverFactory { + + private static WebDriver driver; + + public WebDriver getDriver(){ + WebDriverManager.edgedriver().setup(); + if (driver == null){ + driver = new EdgeDriver(edgeOptions()); + } + return driver; + } + + public EdgeOptions edgeOptions(){ + EdgeOptions edgeOptions = new EdgeOptions(); + + edgeOptions.setHeadless(true); + edgeOptions.addArguments("--disable-gpu"); + edgeOptions.addArguments("--window-size=1920,1200"); + edgeOptions.addArguments("--ignore-certificate-errors"); + edgeOptions.addArguments("--silent"); + edgeOptions.addArguments("--start-maximized"); + + return edgeOptions; + } + +} \ No newline at end of file diff --git a/src/test/java/RunCucumberTest.java b/src/test/java/RunCucumberTest.java new file mode 100644 index 0000000..be77a24 --- /dev/null +++ b/src/test/java/RunCucumberTest.java @@ -0,0 +1,17 @@ +import io.cucumber.testng.AbstractTestNGCucumberTests; +import io.cucumber.testng.CucumberOptions; +import org.testng.annotations.DataProvider; + +@CucumberOptions( + features = {"src/test/resources/features"}, + plugin = {"json:target/cucumber.json", "html:target/site/cucumber-pretty"}, + glue = "src/test/java/step" +) +public class RunCucumberTest extends AbstractTestNGCucumberTests { + + @Override + @DataProvider + public Object[][] scenarios() { + return super.scenarios(); + } +} diff --git a/src/test/java/page/AddProjectPage.java b/src/test/java/page/AddProjectPage.java new file mode 100644 index 0000000..4bdc0d2 --- /dev/null +++ b/src/test/java/page/AddProjectPage.java @@ -0,0 +1,31 @@ +package page; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import utils.BasePage; + +public class AddProjectPage extends BasePage { + + private By nameInputLocator = By.id("name"); + private By accessBtnLocator = By.id("projects-tabs-access"); + private By accessDropdownBtnLocator = By.className("dropdown-icon-black"); + private By designerDropdownLinkLocator = By.xpath("//a[contains(text(), 'Designer')]"); + private By acceptBtnLocator = By.id("accept"); + + public WebElement getNameInput(){ + return service.waitForVisibilityByLocator(nameInputLocator); + } + public WebElement getAccessBtn(){ + return service.waitForVisibilityByLocator(accessBtnLocator); + } + public WebElement getAccessDropdownBtn(){ + return service.waitForVisibilityByLocator(accessDropdownBtnLocator); + } + public WebElement getDesignerDropdownMenuLink(){ + return service.waitForVisibilityByLocator(designerDropdownLinkLocator); + } + public WebElement getAcceptBtn(){ + return service.waitForVisibilityByLocator(acceptBtnLocator); + } + +} diff --git a/src/test/java/page/DashboardPage.java b/src/test/java/page/DashboardPage.java new file mode 100644 index 0000000..5546f82 --- /dev/null +++ b/src/test/java/page/DashboardPage.java @@ -0,0 +1,14 @@ +package page; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import utils.BasePage; + +public class DashboardPage extends BasePage { + + private By addProjectBtnLocator = By.id("sidebar-projects-add"); + + public WebElement getAddProjectBtn(){ + return service.waitForVisibilityByLocator(addProjectBtnLocator); + } +} diff --git a/src/test/java/page/LoginPage.java b/src/test/java/page/LoginPage.java new file mode 100644 index 0000000..8e208b3 --- /dev/null +++ b/src/test/java/page/LoginPage.java @@ -0,0 +1,22 @@ +package page; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import utils.BasePage; + +public class LoginPage extends BasePage { + + private By emailInputLocator = By.id("name"); + private By pswInputLocator = By.id("password"); + private By loginBtn = By.id("button_primary"); + + public WebElement getEmailInput(){ + return service.waitForVisibilityByLocator(emailInputLocator); + } + public WebElement getPassInput(){ + return service.waitForVisibilityByLocator(pswInputLocator); + } + public WebElement getLoginButton(){ + return service.waitForVisibilityByLocator(loginBtn); + } +} diff --git a/src/test/java/page/OverviewPage.java b/src/test/java/page/OverviewPage.java new file mode 100644 index 0000000..d3a8afd --- /dev/null +++ b/src/test/java/page/OverviewPage.java @@ -0,0 +1,26 @@ +package page; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import utils.BasePage; + +public class OverviewPage extends BasePage { + + private By successBannerLocator = By.cssSelector(".message"); + private By deleteBtnLocator = By.xpath("//tr[@class = 'even hoverSensitive']/td[@class='action'][2]"); + private By checkboxLocator = By.xpath("//span[@class = 'dialog-confirm']/strong[contains(text(), 'Yes')]"); + private By confirmButtonLocator = By.xpath("//a[@data-testid = 'caseFieldsTabDeleteDialogButtonOk']"); + + public Boolean isBannerOnPage(){ + return isItemOnAPage(successBannerLocator); + } + public WebElement getDeleteBtn(){ + return service.waitForVisibilityByLocator(deleteBtnLocator); + } + public WebElement getCheckbox(){ + return service.waitForVisibilityByLocator(checkboxLocator); + } + public WebElement getConfirmButton(){ + return service.waitForVisibilityByLocator(confirmButtonLocator); + } +} diff --git a/src/test/java/step/LoginStep.java b/src/test/java/step/LoginStep.java new file mode 100644 index 0000000..63b18ba --- /dev/null +++ b/src/test/java/step/LoginStep.java @@ -0,0 +1,46 @@ +package step; + +import io.cucumber.java.bs.A; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.openqa.selenium.WebDriver; +import org.testng.Assert; +import page.LoginPage; +import web_driver.WebDriverFactory; + +public class LoginStep { + + private LoginPage loginPage; + + private WebDriver driver; + + + public LoginStep(LoginPage loginPage) { + this.loginPage = loginPage; + } + + @Given("driver is ready") + public void openDriver() { + driver = new WebDriverFactory().getDriver(); + driver.get("https://piogjheioghtor.testrail.io/index.php?/auth/login/LWZhMDA0NWExYzgyM2UyNWUzMDVjMjE3ZmRjNzU1ZWEzMjJkOTZmNWY1MWEwODk0MDNjZDJhN2E1NTQ2YTEzM2Y:"); + + } + + @When("perform login with {string} email and {string} password") + public void performLogin(String email, String pass) { + loginPage.getEmailInput().sendKeys(email); + loginPage.getPassInput().sendKeys(pass); + loginPage.getLoginButton().click(); + } + + @Then("Dashboard page is opened") + public void isDashboardPageOpened() { + Assert.assertEquals(driver.getCurrentUrl(), "https://piogjheioghtor.testrail.io/index.php?/dashboard"); + } + + @Then("login page is opened") + public void loginPageIsOpened() { + Assert.assertEquals(driver.getCurrentUrl(), "https://piogjheioghtor.testrail.io/index.php?/auth/login/LWZhMDA0NWExYzgyM2UyNWUzMDVjMjE3ZmRjNzU1ZWEzMjJkOTZmNWY1MWEwODk0MDNjZDJhN2E1NTQ2YTEzM2Y:"); + } +} diff --git a/src/test/java/step/Project.java b/src/test/java/step/Project.java new file mode 100644 index 0000000..e523476 --- /dev/null +++ b/src/test/java/step/Project.java @@ -0,0 +1,45 @@ +package step; + +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.testng.Assert; +import page.AddProjectPage; +import page.DashboardPage; +import page.OverviewPage; + +public class Project { + + private DashboardPage dashboardPage; + private AddProjectPage addProjectPage; + private OverviewPage overviewPage; + + + + public Project(DashboardPage dashboardPage, AddProjectPage addProjectPage, OverviewPage overviewPage) { + this.dashboardPage = dashboardPage; + this.addProjectPage = addProjectPage; + this.overviewPage = overviewPage; + } + + @When("Delete project") + public void deleteProject() { + overviewPage.getDeleteBtn().click(); + overviewPage.getCheckbox().click(); + overviewPage.getConfirmButton().click(); + } + @When("Create project") + public void createProject() { + dashboardPage.getAddProjectBtn().click(); + + addProjectPage.getNameInput().sendKeys("test"); + addProjectPage.getAccessBtn().click(); + addProjectPage.getAccessDropdownBtn().click(); + addProjectPage.getDesignerDropdownMenuLink().click(); + addProjectPage.getAcceptBtn().click(); + } + + @Then("Banner on a page") + public void isBannerOnPage() { + Assert.assertTrue(overviewPage.isBannerOnPage()); + } +} diff --git a/src/test/java/test/LoginTest.java b/src/test/java/test/LoginTest.java new file mode 100644 index 0000000..1d5ac1f --- /dev/null +++ b/src/test/java/test/LoginTest.java @@ -0,0 +1,27 @@ +package test; + +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; +import page.LoginPage; +import step.LoginStep; +import utils.BaseTest; + +public class LoginTest extends BaseTest { + + private LoginStep loginStep; + + @BeforeMethod + public void setUpMethod(){ + loginStep = new LoginStep(new LoginPage()); + driver.get("https://uyfiytfuyl.testrail.io/index.php?/auth/login/LWZhMDA0NWExYzgyM2UyNWUzMDVjMjE3ZmRjNzU1ZWEzMjJkOTZmNWY1MWEwODk0MDNjZDJhN2E1NTQ2YTEzM2Y:"); + } + + @Parameters({"email", "psw"}) + @Test(groups = {"login"}) + public void loginTest(String email, String psw) throws InterruptedException { + loginStep.performLogin(email, psw); + Assert.assertEquals(driver.getCurrentUrl(), "https://uyfiytfuyl.testrail.io/index.php?/dashboard"); + } +} diff --git a/src/test/java/test/ProjectTest.java b/src/test/java/test/ProjectTest.java new file mode 100644 index 0000000..0d66712 --- /dev/null +++ b/src/test/java/test/ProjectTest.java @@ -0,0 +1,34 @@ +package test; + +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import page.AddProjectPage; +import page.DashboardPage; +import page.OverviewPage; +import step.Project; +import utils.BaseTest; + +public class ProjectTest extends BaseTest { + + private Project project; + private OverviewPage overviewPage; + + @BeforeMethod + public void setUpMethod(){ + overviewPage = new OverviewPage(); + project = new Project(new DashboardPage(), new AddProjectPage(), new OverviewPage()); + } + + @Test(groups = {"create project"}, dependsOnGroups = {"login"}) + public void createProjectTest(){ + project.createProject(); + Assert.assertTrue(overviewPage.isBannerOnPage()); + } + + @Test(groups = {"create project"}, dependsOnGroups = {"login"}) + public void deleteProjectTest(){ + project.deleteProject(); + Assert.assertTrue(overviewPage.isBannerOnPage()); + } +} diff --git a/src/test/java/utils/BasePage.java b/src/test/java/utils/BasePage.java new file mode 100644 index 0000000..f4b62d7 --- /dev/null +++ b/src/test/java/utils/BasePage.java @@ -0,0 +1,27 @@ +package utils; + +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebDriver; +import wait_service.WaitService; +import web_driver.WebDriverFactory; + +public class BasePage { + + public static WebDriver webDriver; + public WaitService service; + + public BasePage(){ + WebDriverFactory factory = new WebDriverFactory(); + webDriver = factory.getDriver(); + service = new WaitService(webDriver); + } + + protected Boolean isItemOnAPage(By by){ + try { + return webDriver.findElement(by).isDisplayed(); + } catch (NoSuchElementException e) { + return false; + } + } +} diff --git a/src/test/java/utils/BaseTest.java b/src/test/java/utils/BaseTest.java new file mode 100644 index 0000000..c39219e --- /dev/null +++ b/src/test/java/utils/BaseTest.java @@ -0,0 +1,23 @@ +package utils; + +import org.openqa.selenium.WebDriver; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; +import web_driver.WebDriverFactory; + +public class BaseTest { + + protected static WebDriver driver; + + @BeforeSuite + public void setUp(){ + WebDriverFactory factory = new WebDriverFactory(); + driver = factory.getDriver(); + } + + @AfterSuite + public void wrapUp(){ + driver.quit(); + } +} diff --git a/src/test/resources/features/login.feature b/src/test/resources/features/login.feature new file mode 100644 index 0000000..fa69df9 --- /dev/null +++ b/src/test/resources/features/login.feature @@ -0,0 +1,14 @@ +Feature: Full test rail test + Scenario: Login attempt + Given driver is ready + Then login page is opened + When perform login with "email" email and "pass" password + Then Dashboard page is opened + + Scenario: Create project + When Create project + Then Banner on a page + + Scenario: Delete project + When Delete project + Then Banner on a page \ No newline at end of file