Добавлена проверка в scroll прокрутки до краев

sidebar_filter
Radislav 2025-10-17 08:45:59 +03:00
parent 0a18e12774
commit f9d3a03c68
1 changed files with 177 additions and 39 deletions

View File

@ -114,79 +114,217 @@ class BaseComponent:
return loc.evaluate("el => el.scrollWidth > el.clientWidth")
# Методы прокрутки:
def scroll_up(self, locator: str | Locator) -> None:
"""Прокрутка элемента вверх.
def scroll_up(self, locator: str | Locator, timeout: int = 10000) -> None:
"""Прокрутка элемента до самого верха.
Args:
locator: локатор элемента.
timeout: максимальное время ожидания в мс.
Raises:
AssertionError: если прокрутка не выполнена до верха.
"""
loc = self.get_locator(locator)
max_attempts = 3
attempt = 0
while attempt < max_attempts:
# Получаем текущую позицию прокрутки
previous_position = loc.evaluate("el => el.scrollTop")
# Прокручиваем до верха
loc.evaluate("el => el.scrollTo(0, 0)")
# Ждем завершения прокрутки с использованием timeout
loc.wait_for(timeout=min(2000, timeout))
# Получаем новую позицию прокрутки
current_position = loc.evaluate("el => el.scrollTop")
# Проверяем, достигли ли мы верха
if current_position <= 1: # <= 1 для учета погрешности
return # Успешно прокрутили до верха
# Проверяем, была ли вообще прокрутка
if current_position >= previous_position:
attempt += 1
else:
attempt = 0 # Сбрасываем счетчик, если была прокрутка
# Если вышли из цикла - не смогли прокрутить до верха
final_position = loc.evaluate("el => el.scrollTop")
scroll_height = loc.evaluate("el => el.scrollHeight")
client_height = loc.evaluate("el => el.clientHeight")
raise AssertionError(
f"Не удалось прокрутить до верха. "
f"Текущая позиция: {final_position}, ожидалось: 0, "
f"Высота контента: {scroll_height}, "
f"Высота видимой области: {client_height}"
)
def scroll_down(self, locator: str | Locator, timeout: int = 10000) -> None:
"""Прокрутка элемента до самого конца.
Args:
locator: локатор элемента.
timeout: максимальное время ожидания в мс.
Raises:
AssertionError: если прокрутка не выполнена до конца.
"""
loc = self.get_locator(locator)
loc.evaluate("el => el.scrollTo(0, 0)")
loc.wait_for(timeout=2000)
max_attempts = 3
attempt = 0
# Проверка позиции прокрутки
scroll_position = loc.evaluate("el => el.scrollTop")
assert scroll_position == 0, "Invalid postion after scroll up"
while attempt < max_attempts:
# Получаем текущую позицию прокрутки и размеры
current_position = loc.evaluate("el => el.scrollTop")
scroll_height = loc.evaluate("el => el.scrollHeight")
client_height = loc.evaluate("el => el.clientHeight")
def scroll_down(self, locator: str | Locator) -> None:
"""Прокрутка элемента вниз.
# Проверяем, достигли ли мы конца ДО прокрутки
if current_position + client_height >= scroll_height - 5: # -5 для учета погрешности
return # Уже прокручено до конца
# Прокручиваем до конца
loc.evaluate("el => el.scrollTo(0, el.scrollHeight)")
# Ждем загрузки контента
loc.wait_for(timeout=min(2000, timeout))
# Получаем новую позицию прокрутки
new_position = loc.evaluate("el => el.scrollTop")
new_scroll_height = loc.evaluate("el => el.scrollHeight")
new_client_height = loc.evaluate("el => el.clientHeight")
# Проверяем, достигли ли мы конца
if new_position + new_client_height >= new_scroll_height - 5: # -5 для учета погрешности
return # Успешно прокрутили до конца
# Проверяем, была ли прокрутка
if new_position <= current_position and new_scroll_height <= scroll_height:
# Прокрутки не произошло или контент не изменился
attempt += 1
else:
attempt = 0 # Сбрасываем счетчик, если была прокрутка
# Если вышли из цикла - не смогли прокрутить до конца
final_position = loc.evaluate("el => el.scrollTop")
final_scroll_height = loc.evaluate("el => el.scrollHeight")
final_client_height = loc.evaluate("el => el.clientHeight")
max_scroll_y = final_scroll_height - final_client_height
raise AssertionError(
f"Не удалось прокрутить до конца. "
f"Текущая позиция: {final_position}, ожидалось: {max_scroll_y}, "
f"Высота контента: {final_scroll_height}, "
f"Высота видимой области: {final_client_height}, "
f"Сумма: {final_position + final_client_height}"
)
def scroll_left(self, locator: str | Locator, timeout: int = 10000) -> None:
"""Прокрутка элемента до самого левого края.
Args:
locator: локатор элемента.
timeout: максимальное время ожидания в мс.
Raises:
AssertionError: если прокрутка не выполнена до конца.
AssertionError: если прокрутка не выполнена до левого края.
"""
loc = self.get_locator(locator)
loc.evaluate("el => el.scrollTo(0, el.scrollHeight)")
loc.wait_for(timeout=2000)
max_attempts = 3
attempt = 0
# Проверка позиции прокрутки
scroll_position = loc.evaluate("el => el.scrollTop")
assert scroll_position > 0, "Invalid postion after scroll down"
while attempt < max_attempts:
# Получаем текущую позицию прокрутки
previous_position = loc.evaluate("el => el.scrollLeft")
def scroll_left(self, locator: str | Locator) -> None:
"""Прокрутка элемента влево.
# Прокручиваем до левого края
loc.evaluate("el => el.scrollTo(0, el.scrollTop)")
# Ждем завершения прокрутки с использованием timeout
loc.wait_for(timeout=min(2000, timeout))
# Получаем новую позицию прокрутки
current_position = loc.evaluate("el => el.scrollLeft")
# Проверяем, достигли ли мы левого края
if current_position <= 1: # <= 1 для учета погрешности
return # Успешно прокрутили до левого края
# Проверяем, была ли вообще прокрутка
if current_position >= previous_position:
attempt += 1
else:
attempt = 0 # Сбрасываем счетчик, если была прокрутка
# Если вышли из цикла - не смогли прокрутить до левого края
final_position = loc.evaluate("el => el.scrollLeft")
scroll_width = loc.evaluate("el => el.scrollWidth")
client_width = loc.evaluate("el => el.clientWidth")
raise AssertionError(
f"Не удалось прокрутить до левого края. "
f"Текущая позиция: {final_position}, ожидалось: 0, "
f"Ширина контента: {scroll_width}, "
f"Ширина видимой области: {client_width}"
)
def scroll_right(self, locator: str | Locator, timeout: int = 10000) -> None:
"""Прокрутка элемента до самого правого края.
Args:
locator: локатор элемента.
timeout: максимальное время ожидания в мс.
Raises:
AssertionError: если прокрутка не выполнена до конца.
AssertionError: если прокрутка не выполнена до правого края.
"""
loc = self.get_locator(locator)
max_attempts = 3
attempt = 0
loc.evaluate("el => el.scrollBy(-el.scrollWidth, 0)")
while attempt < max_attempts:
# Получаем текущую позицию прокрутки
previous_position = loc.evaluate("el => el.scrollLeft")
loc.wait_for(timeout=2000)
# Прокручиваем до правого края
loc.evaluate("el => el.scrollTo(el.scrollWidth, el.scrollTop)")
# Проверка позиции прокрутки
scroll_position = loc.evaluate("el => el.scrollLeft")
assert scroll_position == 0, "Invalid postion after scroll left"
# Ждем завершения прокрутки с использованием timeout
loc.wait_for(timeout=min(2000, timeout))
def scroll_right(self, locator: str | Locator) -> None:
"""Прокрутка элемента вправо.
# Получаем новую позицию прокрутки
current_position = loc.evaluate("el => el.scrollLeft")
scroll_width = loc.evaluate("el => el.scrollWidth")
client_width = loc.evaluate("el => el.clientWidth")
Args:
locator: локатор элемента.
# Проверяем, достигли ли мы правого края
max_scroll_x = scroll_width - client_width
if current_position >= max_scroll_x - 1: # -1 для учета погрешности
return # Успешно прокрутили до правого края
Raises:
AssertionError: если прокрутка не выполнена до конца.
"""
# Проверяем, была ли вообще прокрутка
if current_position <= previous_position:
attempt += 1
else:
attempt = 0 # Сбрасываем счетчик, если была прокрутка
loc = self.get_locator(locator)
# Если вышли из цикла - не смогли прокрутить до правого края
final_position = loc.evaluate("el => el.scrollLeft")
scroll_width = loc.evaluate("el => el.scrollWidth")
client_width = loc.evaluate("el => el.clientWidth")
max_scroll_x = scroll_width - client_width
loc.evaluate("el => el.scrollBy(el.scrollWidth, 0)")
loc.wait_for(timeout=2000)
# Проверка позиции прокрутки
scroll_position = loc.evaluate("el => el.scrollLeft")
max_scroll_x = loc.evaluate("el => el.scrollWidth - el.clientWidth")
assert scroll_position >= max_scroll_x, "Invalid postion after scroll right"
raise AssertionError(
f"Не удалось прокрутить до правого края. "
f"Текущая позиция: {final_position}, ожидалось: {max_scroll_x}, "
f"Ширина контента: {scroll_width}, "
f"Ширина видимой области: {client_width}"
)