Initial commit

This commit is contained in:
KamilM1205 2026-01-19 23:32:11 +04:00
commit 9795660e1f
43 changed files with 2757 additions and 0 deletions

View file

View file

@ -0,0 +1,134 @@
import allure
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from tests.ui.pages.base_page import BasePage
class AdminPage(BasePage):
# Локаторы
# Логин
LOGIN_BLOCK = (By.XPATH, "//div[contains(@id, 'operations-user-post_login')]//button[contains(@class, 'opblock-summary-control')]")
LOGIN_TRYITOUT_BTN = (By.XPATH, "//div[contains(@id, 'operations-user-post_login')]//button[contains(@class, 'try-out__btn')]")
LOGIN_TEXTAREA = (By.XPATH, "//div[contains(@id, 'operations-user-post_login')]//textarea[contains(@class, 'body-param__text')]")
LOGIN_EXECUTE_BTN = (By.XPATH, "//div[contains(@id, 'operations-user-post_login')]//button[contains(@class, 'execute')]")
LOGIN_STATUS_CODE = (By.XPATH, "//div[contains(@id, 'operations-user-post_login')]//table[contains(@class, 'live-responses-table')]//tbody//td[contains(@class, 'response-col_status')]")
# Пользователь
USER_BLOCK = (By.XPATH, "//div[contains(@id, 'operations-user-post_team_')]//button[contains(@class, 'opblock-summary-control')]")
USER_TRYITOUT_BTN = (By.XPATH, "//div[contains(@id, 'operations-user-post_team_')]//button[contains(@class, 'try-out__btn')]")
USER_TEXTAREA = (By.XPATH, "//div[contains(@id, 'operations-user-post_team_')]//textarea[contains(@class, 'body-param__text')]")
USER_EXECUTE_BTN = (By.XPATH, "//div[contains(@id, 'operations-user-post_team_')]//button[contains(@class, 'execute')]")
USER_RESPONSE = (By.XPATH, "//div[contains(@id, 'operations-user-post_team_')]//table[contains(@class, 'live-responses-table')]//tbody//td[contains(@class, 'response-col_description')]//code")
USER_STATUS_CODE = (By.XPATH, "//div[contains(@id, 'operations-user-post_team_')]//table[contains(@class, 'live-responses-table')]//tbody//td[contains(@class, 'response-col_status')]")
# Данные для входа
LOGIN_DATA = [Keys.BACKSPACE, Keys.ENTER, '\t"password": "Abc1205",', Keys.ENTER, '\t"username": "muts"', Keys.ENTER, '}']
USER_RAW_DATA = """
"avatar": "🔍",
"description": "QAинженер с фокусом на автоматизированное тестирование и CI/CD.",
"joinDate": "2023-10-01T20:00:00Z",
"motto": "Тестирование — это поиск истины.",
"name": "Андрей Васильев",
"password": "TestPas1205",
"projects": ["Web App Testing", "API Automation"],
"role": "QA Engineer",
"skills": ["Selenium", "JUnit", "Postman", "CI/CD", "TestRail"],
"speciality": "Good user",
"username": "andrey_user"
}
"""
USER_DATA = [Keys.BACKSPACE, USER_RAW_DATA]
def __init__(self, driver: WebDriver):
super().__init__(driver)
@allure.step('Открытие страницы администратора')
def open_admin_page(self):
self.open('http://localhost:8080/swagger/index.html')
@allure.step('Проверка наличия блока логина')
def is_login_block_visible(self):
return self.is_visible(self.LOGIN_BLOCK)
@allure.step('Проверка наличия кнопки "try it out"')
def is_login_tryitout_btn_visible(self):
return self.is_visible(self.LOGIN_TRYITOUT_BTN)
@allure.step('Проверка наличия поля ввода')
def is_login_textarea_visible(self):
return self.is_visible(self.LOGIN_TEXTAREA)
@allure.step('Проверка наличия кнопки выполнения запроса')
def is_login_execute_btn_visible(self):
return self.is_visible(self.LOGIN_EXECUTE_BTN)
@allure.step('Нажатие на блок логина')
def click_login_block(self):
self.click(self.LOGIN_BLOCK)
@allure.step('Нажатие на кнопку "try it out"')
def click_login_tryitout_btn(self):
self.click(self.LOGIN_TRYITOUT_BTN)
@allure.step('Ввод текста в поле логина')
def enter_text_to_login_textarea(self, text: list):
field = self.find_element(self.LOGIN_TEXTAREA)
field.clear()
for event in text:
field.send_keys(event)
@allure.step('Нажатие на кнопку выполнения запроса')
def click_login_execute_btn(self):
self.click(self.LOGIN_EXECUTE_BTN)
@allure.step('Получение статуса выполнения входа')
def get_login_status(self):
return self.get_text(self.LOGIN_STATUS_CODE)
@allure.step('Проверка наличия блока пользователя')
def is_user_block_visible(self):
return self.is_visible(self.USER_BLOCK)
@allure.step('Проверка наличия кнопки "try it out"')
def is_user_tryitout_btn_visible(self):
return self.is_visible(self.USER_TRYITOUT_BTN)
@allure.step('Проверка наличия поля ввода')
def is_user_textarea_visible(self):
return self.is_visible(self.USER_TEXTAREA)
@allure.step('Проверка наличия кнопки выполнения запроса')
def is_user_execute_btn_visible(self):
return self.is_visible(self.USER_EXECUTE_BTN)
@allure.step('Нажатие на блок пользователя')
def click_user_block(self):
self.click(self.USER_BLOCK)
@allure.step('Нажатие на кнопку "try it out"')
def click_user_tryitout_btn(self):
self.click(self.USER_TRYITOUT_BTN)
@allure.step('Ввод текста в поле добавления пользователя')
def enter_text_to_user_textarea(self, text: list):
field = self.find_element(self.USER_TEXTAREA)
field.clear()
for event in text:
field.send_keys(event)
@allure.step('Нажатие на кнопку выполнения запроса')
def click_user_execute_btn(self):
self.click(self.USER_EXECUTE_BTN)
@allure.step('Получение ответа на запрос создания пользователя')
def get_user_response(self):
elem = self.find_element(self.USER_RESPONSE)
return elem.get_attribute('innerText')
@allure.step('Получение статуса создания пользователя')
def get_user_status(self):
return self.get_text(self.USER_STATUS_CODE)

View file

@ -0,0 +1,99 @@
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import allure
import logging
logger = logging.getLogger(__name__)
class BasePage:
def __init__(self, driver: WebDriver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
self.logger = logger
@allure.step("Открыть URL: {url}")
def open(self, url):
self.driver.get(url)
self.logger.info(f"Открыта страница: {url}")
@allure.step("Обновить страницу")
def refresh(self):
self.driver.refresh()
self.logger.info("Страница обновлена")
@allure.step("Найти элемент: {locator}")
def find_element(self, locator):
try:
element = self.wait.until(EC.visibility_of_element_located(locator))
self.logger.debug(f"Элемент найден: {locator}")
return element
except TimeoutException:
self.logger.error(f"Элемент не найден: {locator}")
allure.attach(
self.driver.get_screenshot_as_png(),
name="element_not_found",
attachment_type=allure.attachment_type.PNG
)
raise
@allure.step("Кликнуть на элемент: {locator}")
def click(self, locator):
element = self.find_element(locator)
element.click()
self.logger.info(f"Клик по элементу: {locator}")
@allure.step("Ввести текст '{text}' в элемент: {locator}")
def type_text(self, locator, text):
element = self.find_element(locator)
element.clear()
element.send_keys(text)
self.logger.info(f"Введен текст '{text}' в элемент: {locator}")
@allure.step("Получить текст элемента: {locator}")
def get_text(self, locator):
element = self.find_element(locator)
text = element.text
self.logger.info(f"Получен текст '{text}' из элемента: {locator}")
return text
@allure.step("Проверить, что элемент видим: {locator}")
def is_visible(self, locator):
try:
element = self.find_element(locator)
is_displayed = element.is_displayed()
self.logger.info(f"Элемент {locator} видим: {is_displayed}")
return is_displayed
except (TimeoutException, NoSuchElementException):
return False
@allure.step("Получить текущий URL")
def get_current_url(self):
url = self.driver.current_url
self.logger.info(f"Текущий URL: {url}")
return url
@allure.step("Сделать скриншот")
def take_screenshot(self, name="screenshot"):
screenshot = self.driver.get_screenshot_as_png()
allure.attach(
screenshot,
name=name,
attachment_type=allure.attachment_type.PNG
)
self.logger.info(f"Скриншот сохранен: {name}")
@allure.step("Ожидание загрузки элемента: {locator}")
def wait_for_element(self, locator, timeout=10):
wait = WebDriverWait(self.driver, timeout)
element = wait.until(EC.visibility_of_element_located(locator))
self.logger.info(f"Элемент загружен: {locator}")
return element
@allure.step("Скролл до элемента")
def scroll_to_element(self, locator):
element = self.find_element(locator)
self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", element)

View file

@ -0,0 +1,92 @@
import allure
from selenium.webdriver.common.by import By
from config.ui_config import UIConfig
from tests.ui.pages.base_page import BasePage
class HomePage(BasePage):
# Локаторы
LOGO = (By.CLASS_NAME, "logo-text")
TEAM_TITLE = (By.XPATH, "//div[contains(@class, 'team-panel')]//h3")
ARTICLE_TITLE = (By.XPATH, "//div[contains(@class, 'blog-panel')]//h3")
TIME = (By.ID, "current-time")
TEAM_SECTION = (By.CLASS_NAME, "team-carousel")
ARTICLE_SECTION = (By.CLASS_NAME, "articles-list")
TEAM_NOT_FOUND = (By.XPATH, "//div[contains(@class, 'team-carousel')]//div[contains(@class, 'empty-state')]/span[not(contains(@class, 'empty-icon'))]")
ARTICLE_NOT_FOUND = (By.XPATH, "//div[contains(@class, 'articles-list')]//div[contains(@class, 'empty-state')]/span[not(contains(@class, 'empty-icon'))]")
AUTHOR_CARD = (By.CLASS_NAME, "team-member-card")
ARTICLE_CARD = (By.CLASS_NAME, "article-preview")
TEAM_VIEW_ALL = (By.XPATH, "//div[contains(@class, 'team-panel')]//a[contains(@class, 'view-all')]")
ARTICLE_VIEW_ALL = (By.XPATH, "//div[contains(@class, 'blog-panel')]//a[contains(@class, 'view-all')]")
def __init__(self, driver):
super().__init__(driver)
@allure.step("Открытие домашней страницы")
def open_home_page(self):
self.open(UIConfig.UI_BASE_URL)
@allure.step("Проверка большого лого")
def check_home_logo(self):
text = self.get_text(self.LOGO)
assert text == "Team"
return text
@allure.step("Проверка заголовка списка команды")
def check_home_team(self):
text = self.get_text(self.TEAM_TITLE)
assert text == "MEET THE TEAM"
return text
@allure.step("Проверка заголовка списка постов")
def check_home_posts(self):
text = self.get_text(self.ARTICLE_TITLE)
assert text == "LATEST ARTICLES"
return text
@allure.step("Проверить наличие раздела 'Meet the Team'")
def is_meet_the_team_section_displayed(self):
return self.is_visible(self.TEAM_SECTION)
@allure.step("Проверить наличие раздела 'Latest Articles'")
def is_latest_articles_section_displayed(self):
return self.is_visible(self.ARTICLE_SECTION)
@allure.step("Проверить сообщение 'No team members found'")
def check_no_team_members_message(self):
message = self.get_text(self.TEAM_NOT_FOUND)
assert "No team members found" in message, \
f"Ожидалось сообщение 'No team members found', получено '{message}'"
return message
@allure.step("Проверить сообщение 'No articles found'")
def check_no_articles_message(self):
message = self.get_text(self.ARTICLE_NOT_FOUND)
assert "No articles found" in message, \
f"Ожидалось сообщение 'No articles found', получено '{message}'"
return message
@allure.step("Проверить наличие карточки автора")
def is_member_card_displayed(self):
return self.is_visible(self.AUTHOR_CARD)
@allure.step("Проверить наличие карточки статьи")
def is_article_card_displayed(self):
return self.is_visible(self.ARTICLE_CARD)
@allure.step("Проверить видимость кнопки VIEW ALL TEAM")
def is_team_view_all_displayed(self):
return self.is_visible(self.TEAM_VIEW_ALL)
@allure.step("Проверить видимость кнопки VIEW ALL TEAM")
def is_article_view_all_displayed(self):
return self.is_visible(self.ARTICLE_VIEW_ALL)
@allure.step("Проверить кликабельность кнопки VIEW ALL TEAM")
def click_view_all_team_button(self):
self.click(self.TEAM_VIEW_ALL)
@allure.step("Проверить кликабельность кнопки VIEW ALL TEAM")
def click_view_all_article_button(self):
self.click(self.ARTICLE_VIEW_ALL)