diff --git a/pom.xml b/pom.xml index 11a796c..056d8a9 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.9.6 1.14.0 2.22.2 - 6.2.0 + 6.19.1 2.15.0 1.7.30 3.8.1 @@ -212,6 +212,12 @@ jackson-databind ${jackson.version} + + + io.github.bonigarcia + webdrivermanager + 5.5.3 + \ No newline at end of file diff --git a/src/main/java/ru/lanit/at/pages/LoginPage.java b/src/main/java/ru/lanit/at/pages/LoginPage.java new file mode 100644 index 0000000..fac4cb1 --- /dev/null +++ b/src/main/java/ru/lanit/at/pages/LoginPage.java @@ -0,0 +1,53 @@ +package ru.lanit.at.pages; + +import com.codeborne.selenide.SelenideElement; +import io.qameta.allure.Step; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.PageFactory; +import ru.lanit.at.utils.web.pagecontext.WebPage; +import ru.lanit.at.utils.web.annotations.Name; + +import static com.codeborne.selenide.Selenide.$x; +import static com.codeborne.selenide.Selenide.$; +/** Страница логина */ +@Name(value = "Авторизация") +public class LoginPage extends WebPage { + + @Name("поле логина") + private SelenideElement username = $x("//*[@id='username']"); + + @Name("поле пароля") + private SelenideElement password = $("#password"); + + @Name("кнопка входа") + private SelenideElement loginButton = $("[type='submit']"); + + /** + * Авторизация пользователя + * + * @param user логин пользователя + * @param pass пароль пользователя + */ + public LoginPage login(String user, String pass) { + setUser(user); + setPassword(pass); + clickOnLoginButton(); + return this; + } + + public LoginPage setUser(String user) { + getElement("поле логина").setValue(user); + return this; + } + + public LoginPage setPassword(String pass) { + getElement("поле пароля").setValue(pass); + return this; + } + + public LoginPage clickOnLoginButton() { + getElement("кнопка входа").click(); + return this; + } +} diff --git a/src/main/java/ru/lanit/at/pages/TicketPage.java b/src/main/java/ru/lanit/at/pages/TicketPage.java new file mode 100644 index 0000000..283b0d2 --- /dev/null +++ b/src/main/java/ru/lanit/at/pages/TicketPage.java @@ -0,0 +1,43 @@ +package ru.lanit.at.pages; + +import com.codeborne.selenide.SelenideElement; +import io.qameta.allure.Step; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.testng.Assert; +import ru.lanit.at.utils.web.pagecontext.WebPage; +import ru.lanit.at.utils.web.annotations.Name; + +import static com.codeborne.selenide.Selenide.$x; +import static com.codeborne.selenide.Selenide.$; + +/** Страница отдельного тикета (авторизированный пользователь) */ +@Name(value = "Страница тикета") +public class TicketPage extends WebPage { + + @Name("заголовок тикета") + private SelenideElement title = $x("//th[@colspan='4']/h3"); + + @Name("очередь") + private SelenideElement queue = $x("//th[contains(text(), 'Queue:')]"); + + @Name("дата выполнения") + private SelenideElement dueDate = $x("//th[text()='Due Date']/following-sibling::td[1]"); + + @Name("email") + private SelenideElement email = $x("//th[text()='Submitter E-Mail']/following-sibling::td[1]"); + + @Name("приоритет") + private SelenideElement priority = $x("//th[text()='Priority']/following-sibling::td[1]"); + + @Name("описание") + private SelenideElement description = $x("//td[@id='ticket-description']/p"); + + @Name("добавить файлы") + private SelenideElement buttonAddFiles = $x("//button[@id='ShowFileUpload']"); + + @Name("выбрать файл") + private SelenideElement selectFile = $(".btn-file"); + +} + diff --git a/src/main/java/ru/lanit/at/pages/TicketsPage.java b/src/main/java/ru/lanit/at/pages/TicketsPage.java new file mode 100644 index 0000000..977e23b --- /dev/null +++ b/src/main/java/ru/lanit/at/pages/TicketsPage.java @@ -0,0 +1,70 @@ +package ru.lanit.at.pages; + +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.SelenideElement; +import io.qameta.allure.Step; +import ru.lanit.at.utils.web.pagecontext.WebPage; +import ru.lanit.at.utils.web.annotations.Name; + +import java.util.List; + +import static com.codeborne.selenide.Selenide.*; + +/** Страница с таблицей тикетов и фильтрами */ +@Name(value = "Список тикетов") +public class TicketsPage extends WebPage { + + @Name("ссылки на тикеты") + private ElementsCollection ticketsHref = $$x("//div[@class='tickettitle']/a"); + + @Name("поле поиска") + private SelenideElement search = $("#search_query"); + + @Name("кнопка поиска") + private SelenideElement searchButton = $x("//i[@class='fas fa-search']/parent::button"); + + public TicketsPage clickOnSearch(String title) { + getElement("поле поиска").clear(); + getElement("поле поиска").setValue(title); + getElement("кнопка поиска").click(); + return this; + } + @Name("сортировка") + private SelenideElement sortingBy = $x("//select[@id='id_sortx']"); + + @Name("сортировка по названию") + private SelenideElement sortingByField = $x("//select[@id='id_sortx']/option[@value='title']"); + + @Name("чекбокс обратного порядка") + private SelenideElement inputReverse = $x("//input[@id='id_sortreverse']"); + + @Name("выпадающий список добавления фильтра") + private SelenideElement addFilter = $x("//select[@id='filterBuilderSelect']"); + + @Name("фильтр на очередь") + private SelenideElement addFilterQueue = $x("//select[@id='filterBuilderSelect']/option[@id='filterBuilderSelect-Queue']"); + + @Name("очередь тикета") + private SelenideElement addFilterQueueValue = $x("//select[@id='id_queues']/option[@value='1']"); + + @Name("статус тикета") + private SelenideElement statusTicket = $x("//select[@id='id_statuses']/option[@value='1']"); + + @Name("кнопка для применения фильтра") + private SelenideElement buttonApply = $x("//input[@value='Apply Filters']"); + + @Name("таба для сохранения поискового запроса") + private SelenideElement queryTab = $x("//button[@data-target='#collapseTwo']"); + + @Name("название сохраненного поискового запроса") + private SelenideElement queryTitle = $x("//input[@id='id_title']"); + + @Name("кнопка сохранить поисковый запрос") + private SelenideElement querySaveButton = $x("//input[@value='Save Query']"); + + @Name("кнопка для отображения сохраненных запросов") + private SelenideElement savedQueries = $x("//a[@id='ticketsDropdown']"); + /** + * @param ticket + */ +} diff --git a/src/main/java/ru/lanit/at/steps/web/pages/TicketPageWebSteps.java b/src/main/java/ru/lanit/at/steps/web/pages/TicketPageWebSteps.java new file mode 100644 index 0000000..98c61a7 --- /dev/null +++ b/src/main/java/ru/lanit/at/steps/web/pages/TicketPageWebSteps.java @@ -0,0 +1,60 @@ +package ru.lanit.at.steps.web.pages; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selectors; +import com.codeborne.selenide.SelenideElement; +import io.cucumber.java.ru.Если; +import io.cucumber.java.ru.Когда; +import org.openqa.selenium.By; +import ru.lanit.at.steps.web.AbstractWebSteps; +import ru.lanit.at.utils.web.pagecontext.PageManager; + +import static com.codeborne.selenide.Condition.*; +import static com.codeborne.selenide.Selenide.$; +import static com.codeborne.selenide.Selenide.$x; + +public class TicketPageWebSteps extends AbstractWebSteps { + + public TicketPageWebSteps(PageManager pageManager) { + super(pageManager); + } + + @Если("загрузить файл {string}") + public void uploadFile(String fileName) { + SelenideElement fileInput = $("#file0"); + fileInput.uploadFromClasspath(fileName); + LOGGER.info("загружен файл '{}'", fileName); + } + + @Если("проверить что на странице прикреплен файл {string}") + public void checkFileAttached(String fileName) { + $("#selectedfilename0").shouldBe(text(fileName)); + } + + @Когда("на странице присутствует часть текста {string}") + public void textContainsOnPage(String text) { + $x(".//*[contains(text(), '" + text + "')]").shouldBe(Condition.visible); + LOGGER.info("на странице присутствует часть текста '{}'", text); + } + + @Когда("кликнуть на элемент где присутствует часть текста {string}") + public void clickOnElementByContainsText(String text) { + $x(".//*[contains(text(), '" + text + "')]") + .shouldBe(Condition.visible) + .click(); + LOGGER.info("клик на элемент, содержащий текст '{}'", text); + } + + @Если("на странице есть название поискового запроса {string}") + public void checkTitle(String title) { + $x("//a[@class='dropdown-item small' and normalize-space(.)='" + title + "']") + .shouldBe(Condition.visible); + } + + @Если("кликнуть на название поискового запроса {string}") + public void clickSearchQuery(String title) { + $x("//a[@class='dropdown-item small' and normalize-space(.)='" + title + "']") + .shouldBe(Condition.visible) + .click(); + } +} diff --git a/src/test/java/Runner.java b/src/test/java/Runner.java index 1958636..a94966a 100644 --- a/src/test/java/Runner.java +++ b/src/test/java/Runner.java @@ -8,13 +8,14 @@ import org.testng.annotations.DataProvider; "pretty", "io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm" }, - features = "classpath:features", + tags = "@helpdesk", + features = {"classpath:features/"}, glue = {"ru.lanit.at.steps", "ru.lanit.at.hooks", "ru.lanit.at.corecommonstep"} ) public class Runner extends AbstractTestNGCucumberTests { @Override - @DataProvider(parallel = true) + @DataProvider(parallel = false) public Object[][] scenarios() { return super.scenarios(); diff --git a/src/test/resources/json/authToken.json b/src/test/resources/json/authToken.json new file mode 100644 index 0000000..52490f2 --- /dev/null +++ b/src/test/resources/json/authToken.json @@ -0,0 +1,4 @@ +{ + "username": "${username}", + "password": "${password}" +} \ No newline at end of file diff --git a/src/test/resources/json/ticket.json b/src/test/resources/json/ticket.json new file mode 100644 index 0000000..531d3a0 --- /dev/null +++ b/src/test/resources/json/ticket.json @@ -0,0 +1,8 @@ +{ + "title": "${title}", + "queue": "${queue}", +"description": "${description}", +"priority": "${priority}", +"submitter_email": "${submitter_email}", +"status": "${status}" +} \ No newline at end of file