Merge pull request 'Initial commit' (#2) from cucumber_homework into cucumber_master

Reviewed-on: paninvaleriy/homework#2
This commit is contained in:
Панин 2026-08-18 12:21:13 +00:00
commit dbc4e37ca7
8 changed files with 248 additions and 3 deletions

View File

@ -16,7 +16,7 @@
<aspectj.version>1.9.6</aspectj.version>
<aspectj-maven-plugin.version>1.14.0</aspectj-maven-plugin.version>
<surefire.version>2.22.2</surefire.version>
<selenide.version>6.2.0</selenide.version>
<selenide.version>6.19.1</selenide.version>
<log4j.version>2.15.0</log4j.version>
<slf4j.version>1.7.30</slf4j.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
@ -212,6 +212,12 @@
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>5.5.3</version>
</dependency>
</dependencies>
</project>

View File

@ -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;
}
}

View File

@ -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");
}

View File

@ -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
*/
}

View File

@ -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();
}
}

View File

@ -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();

View File

@ -0,0 +1,4 @@
{
"username": "${username}",
"password": "${password}"
}

View File

@ -0,0 +1,8 @@
{
"title": "${title}",
"queue": "${queue}",
"description": "${description}",
"priority": "${priority}",
"submitter_email": "${submitter_email}",
"status": "${status}"
}