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