e-nms_qa_automation.1/pages/base_page.py

296 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from playwright.sync_api import Page, TimeoutError, Response, APIRequestContext, expect
from data.environment import host
from Locators.base_page import BasePageLocators
import time
import json
class BasePage:
def __init__(self, page: Page):
self.page = page
self.token = ""
def open(self, uri) -> Response | None:
return self.page.goto(f"{host.get_base_url()}{uri}", wait_until='domcontentloaded')
def get_api_request_context(self) -> APIRequestContext:
return self.page.context.request
#return page url
def current_url(self) -> str:
return self.page.url
# click on element
def click(self, locator: str) -> None:
self.page.click(locator)
# input in field
def input(self, locator: str, data: str) -> None:
self.page.locator(locator).fill(data)
# clear input field
def clear_input(self, locator: str) -> None:
self.page.locator(locator).press('Control+A')
self.page.locator(locator).press('Backspace')
def page_reload(self) ->None:
self.page.reload()
# wait for element
def wait_for_element(self, locator, timeout=12000) -> None:
self.page.wait_for_selector(locator, timeout=timeout)
# wait for all elements
def wait_for_all_elements(self, locator, timeout=5000):
elements = self.page.query_selector_all(locator)
for element in elements:
self.page.wait_for_selector(locator, timeout=timeout)
return elements
# if element presents then ok
def is_element_present(self, locator: str, timeout: int = 5000) -> bool:
try:
self.page.wait_for_selector(locator, timeout=timeout)
except TimeoutError:
return False
return True
# if element is not present then ok
def is_element_NOT_presence(self, locator: str, timeout: int = 5000) -> bool:
try:
self.page.wait_for_selector(locator, timeout=timeout)
except TimeoutError:
return True
return False
# get text. If we have once locator then index is 0
def get_text(self, locator: str, index: int) -> str:
return self.page.locator(locator).nth(index).text_content()
# Traverse the table
def read_table_data(self, locator) -> []:
table_data = []
table = self.page.locator(locator)
# read table header
header_cells = table.locator(BasePageLocators.TABLE_HEADERS_CELLS)
header_data = []
for h in range(header_cells.count()):
header_cell_text = header_cells.nth(h).inner_text()
header_data.append(header_cell_text)
table_data.append(header_data)
# read table cells by rows
rows = table.locator(BasePageLocators.TABLE_BODY)
for i in range(rows.count()):
row = rows.nth(i)
cells = row.locator("td")
row_data = []
for j in range(cells.count()):
cell_text = cells.nth(j).inner_text()
row_data.append(cell_text)
table_data.append(row_data)
return table_data
# send get request to api
def send_get_api_request(self, uri):
api_request_context = self.get_api_request_context()
token = host.get_access_token()
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
response = api_request_context.get(f"{host.get_base_url()}{uri}", headers = headers)
return response
# send get request to api
def send_post_api_request(self, uri, payload):
api_request_context = self.get_api_request_context()
token = host.get_access_token()
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
response = api_request_context.post(f"{host.get_base_url()}{uri}", headers = headers, data=payload)
return response
# get response body
def get_response_body(self, response):
try:
response_body = response.json()
except json.JSONDecodeError:
print("Failed to decode JSON response")
return None
return response_body
def should_be_horizontal_scroll(self) -> None:
"""
Проверяет горизонтальный скролл с плавной прокруткой.
"""
modal_selector = "div.v-dialog.v-dialog--active"
modal = self.page.locator(modal_selector).first
try:
# Ожидаем появления окна
modal.wait_for(state="visible", timeout=5000)
# Получаем размеры через page.evaluate
scroll_data = self.page.evaluate("""() => {
const modal = document.querySelector('div.v-dialog.v-dialog--active');
return {
scrollWidth: modal.scrollWidth,
clientWidth: modal.clientWidth,
scrollLeft: modal.scrollLeft
};
}""")
print(f"Окно: Общая ширина: {scroll_data['scrollWidth']}px, "
f"Видимая область: {scroll_data['clientWidth']}px, "
f"Начальная позиция: {scroll_data['scrollLeft']}px")
if scroll_data['scrollWidth'] > scroll_data['clientWidth']:
print("Тестируем скролл...")
# Плавный скролл вправо
self.page.evaluate("""() => {
const modal = document.querySelector('div.v-dialog.v-dialog--active');
return new Promise(resolve => {
const target = modal.scrollWidth - modal.clientWidth;
const duration = 1000;
const start = modal.scrollLeft;
const startTime = performance.now();
function scrollStep(timestamp) {
const progress = (timestamp - startTime) / duration;
modal.scrollLeft = start + (target - start) * Math.min(progress, 1);
if (progress < 1) {
window.requestAnimationFrame(scrollStep);
} else {
resolve();
}
}
window.requestAnimationFrame(scrollStep);
});
}""")
# Проверяем конечную позицию
final_scroll = self.page.evaluate("""() => {
return document.querySelector('div.v-dialog.v-dialog--active').scrollLeft;
}""")
print("Успешно проскроллили вправо")
# Плавный скролл влево
self.page.evaluate("""() => {
const modal = document.querySelector('div.v-dialog.v-dialog--active');
return new Promise(resolve => {
const duration = 1000;
const start = modal.scrollLeft;
const startTime = performance.now();
function scrollStep(timestamp) {
const progress = (timestamp - startTime) / duration;
modal.scrollLeft = start - start * Math.min(progress, 1);
if (progress < 1) {
window.requestAnimationFrame(scrollStep);
} else {
resolve();
}
}
window.requestAnimationFrame(scrollStep);
});
}""")
# Проверяем возврат в начало
final_scroll = self.page.evaluate("""() => {
return document.querySelector('div.v-dialog.v-dialog--active').scrollLeft;
}""")
assert final_scroll == 0, "Не удалось вернуться в начальную позицию скролла"
print("Успешно проскроллили влево")
else:
print("Окно не требует горизонтального скролла.")
except Exception as e:
print(f"Ошибка при проверке скролла окна: {str(e)}")
raise
def should_be_vertical_scroll(self, wrapper_selector: str = "div.scrolltable__wrapper") -> None:
"""
Проверяет вертикальный скролл в указанном контейнере.
Args:
wrapper_selector: CSS-селектор скроллируемого контейнера.
По умолчанию: "div.scrolltable__wrapper".
"""
# Ожидаем загрузки таблицы
table_wrapper = self.page.locator(wrapper_selector).first
table_wrapper.wait_for(state="visible", timeout=10000)
try:
# Пытаемся найти скроллируемый элемент с небольшим таймаутом
scrollable_element = table_wrapper.locator("tbody.scrolltable__scroll").first
scrollable_element.wait_for(state="attached", timeout=3000)
# Проверяем параметры скролла
scroll_height = scrollable_element.evaluate("el => el.scrollHeight")
client_height = scrollable_element.evaluate("el => el.clientHeight")
scroll_data = scrollable_element.evaluate("el => el.scrollLeft")
print(f"Окно: Общая ширина: {scroll_height}px, "
f"Видимая область: {client_height}px, "
f"Начальная позиция: {scroll_data}px")
if scroll_height > client_height:
print("Тестируем скролл...")
# 1. Плавный скролл вниз
scrollable_element.evaluate("""el => {
const target = el.scrollHeight;
const duration = 1000;
const start = el.scrollTop;
const startTime = performance.now();
function scrollStep(timestamp) {
const progress = (timestamp - startTime) / duration;
el.scrollTop = start + (target - start) * Math.min(progress, 1);
if (progress < 1) {
window.requestAnimationFrame(scrollStep);
}
}
window.requestAnimationFrame(scrollStep);
}""")
time.sleep(1.5) # Ожидаем завершения скролла
# Проверяем последнюю строку
last_row = table_wrapper.locator("tbody tr").last
expect(last_row).to_be_visible()
print("Успешно проскроллили вниз")
# 2. Плавный скролл вверх
scrollable_element.evaluate("""el => {
const duration = 1000;
const start = el.scrollTop;
const startTime = performance.now();
function scrollStep(timestamp) {
const progress = (timestamp - startTime) / duration;
el.scrollTop = start - start * Math.min(progress, 1);
if (progress < 1) {
window.requestAnimationFrame(scrollStep);
}
}
window.requestAnimationFrame(scrollStep);
}""")
time.sleep(1.5) # Ожидаем завершения скролла
# Проверяем первую строку
first_row = table_wrapper.locator("tbody tr").first
expect(first_row).to_be_visible()
print("Успешно проскроллили вверх")
else:
print("Весь контент виден без скролла")
except Exception as e:
print(f"Элемент для скролла не найден или не скроллится: {e}")
# Проверяем, есть ли хотя бы строки в таблице
rows = table_wrapper.locator("tbody tr")
if rows.count() > 0:
print(f"Найдено {rows.count()} строк в таблице без скролла")
else:
print("Таблица пуста или не найдена")