
from types import NoneType
from typing import Union, TypeVar
from selenium.webdriver.remote.webdriver import BaseWebDriver
from selenium.webdriver.remote.webelement import BaseWebElement

from core_dsl import FP, SP, NP, EP

T = TypeVar("T")
TIMEOUT   = Union[float, int, NoneType]
SELECTOR  = Union[str, FP, SP, NP, EP, BaseWebElement]
SELECTORS = Union[SELECTOR, list[SELECTOR]]

class Browser:
	def __init__(self, name: str):
		pass
	
	def get_driver(self) -> BaseWebDriver:
		"""
		Возвращает текущий объект WebDriver
		"""
	
	def get_logs(self) -> dict:
		"""
		Логи selenium-а
		"""
	
	def get_links(self) -> dict:
		"""
		Возвращает словарь ссылок
		"""
	
	def maximize(self):
		"""
		Разворачивает окно броузера
		"""
	
	def fullscreen(self):
		"""
		Полноэкранный режим
		"""
	
	def minimize(self):
		"""
		Сворачивает окно броузера
		"""
	
	def rect(self, selector: Union[SELECTOR, NoneType], wait_timeout: TIMEOUT) -> (int, int, int, int):
		"""
		Возвращает размеры окна или элемента
		"""
	
	def set_rect(self, x: int, y: int, width: int, height: int):
		"""
		Устанавливает геометрию окна броузера
		"""
	
	def get_elements(self, selector: SELECTOR, displayed: bool, enabled:bool, wait_timeout: TIMEOUT) -> tuple[BaseWebElement]:
		"""
		Возвращаем список элементов соответствующих селектору
		"""
	
	def is_not_element(self, selector: SELECTORS, wait_timeout: TIMEOUT) -> bool:
		"""
		Возвращает True если элемент находится на странице
		displayed      - элемент должен быть визуализирован
		staleness_wait - Ждать пока элемент не исчезнет
		"""
	
	def get_element(self, selector: SELECTOR, displayed: bool, enabled: bool, wait_timeout: TIMEOUT) -> BaseWebElement:
		"""
		Возвращаем элемент соответствующий селектору
		"""
	
	def focused(self, el: BaseWebElement):
		"""
		Передаём фокус элементу
		"""
	
	def scroll(self, selector: SELECTOR, offset_x: int, offset_y: int, forced: bool, wait_timeout: TIMEOUT):
		"""
		Перемещает прокрутку до появления элемента selector
		"""
	
	def double_click(self, selector: SELECTOR, wait_timeout: TIMEOUT):
		"""
		Двойной клик
		"""
	
	def mouse_menu(self, selector: SELECTOR, wait_timeout: TIMEOUT):
		"""
		Контекстное меню
		"""
	
	def move_mouse(self, selector: SELECTOR, x: int, y: int, wait_timeout: TIMEOUT):
		"""
		Перемещение мыши на элемент
		"""
	
	def drag_and_drop(self, selector1: SELECTOR, selector2: SELECTOR, wait_timeout: TIMEOUT):
		"""
		Перетаскивание
		"""
	
	def drag_and_drop_offset(self, selector: SELECTOR, x: int, y: int, wait_timeout: TIMEOUT):
		"""
		Перетаскивание на координаты
		"""
	
	def get_url(self, url: str, timeout: TIMEOUT) -> (str, float):
		"""
		Переходим на страницу с указанным URL. Возвращает время загрузки страницы
		"""
	
	def refresh(self, timeout: TIMEOUT):
		"""
		Перезагрузка страницы
		"""
	
	def back(self, timeout: TIMEOUT):
		"""
		Перемещение назад по истории
		"""
	
	def forward(self, timeout: TIMEOUT):
		"""
		Перемещение вперёд по истории
		"""
	
	def set_data(self, selector: SELECTOR, data: str, multi_selector: bool, clear: bool, delay: float, key: str, click: bool, offset_x: int, offset_y: int, wait_timeout: TIMEOUT):
		"""
		Установка данных для элемента
		"""
	
	def clear(self, selector: SELECTOR, multi_selector: bool, wait_timeout: TIMEOUT):
		"""
		Очистить данные элемента
		"""
	
	def click(self, selector: SELECTOR, multi_selector: bool, offset_x: int, offset_y: int, js: bool, wait_timeout: TIMEOUT):
		"""
		Клин на элементе
		"""
	
	def set_key(self, selector: str, key: str, multi_selector: bool, wait_timeout: TIMEOUT):
		"""
		Нажатие клавиши
		"""
	
	def run_js(self, js: str, *args, sync: bool, ignor_except: tuple, timeout: TIMEOUT):
		"""
		Выполнить JS
		"""
	
	def frame(self, selector: SELECTOR, scroll: bool, wait_timeout: TIMEOUT):
		"""
		Переключаемся на фрейм
		"""
	
	def new_window(self, url: str, tab: bool, wait_timeout: TIMEOUT):
		"""
		Открывает новую вкладку или окно (если tab == True)
		"""
	
	def window(self, handle: int):
		"""
		Переключаемся на окно/вкладку
		"""
	
	def close_window(self, handle: int):
		"""
		Закрывает текущие (или с указанным handle) окно/вкладку
		после чего переключается на предыдущее окно/вкладку
		"""
	
	def screenshot(self, selector: SELECTOR, wait_timeout: TIMEOUT) -> bytes:
		"""
		Возвращает скриншот страницы или элемента
		"""
	
	def del_cookies(self, name: Union[str, list[str]]):
		"""
		Удаляет cookies с идентификатором name
		"""
	
	def get_cookies(self, name: str) -> dict:
		"""
		Возвращает все cookies или одну cookies с идентификатором name
		"""
	
	def set_cookies(self, cookie: Union[dict, tuple, list]):
		"""
		Добавляет cookies.
		"""
	
	def set_attribute(self, selector: SELECTOR, attribute: str, value: str, wait_timeout: TIMEOUT):
		"""
		Установка значения атрибута для элемента
		"""
	
	def upload(self, selector: SELECTOR, path: str, wait_timeout: TIMEOUT):
		"""
		Загрузка файла
		"""
	
	def get_download_file(self, name: str, null: bool, wait_timeout: TIMEOUT):
		"""
		Возвращает пить к скаченному файлу
		"""
	
	def download_md5(self, name: str, wait_timeout: TIMEOUT):
		"""
		Возвращает MD5 скаченного файла
		"""
	
	def download_size(self, name: str, wait_timeout: TIMEOUT):
		"""
		Возвращает размер скаченного файла
		"""
	
	def test_status_code(self):
		"""
		Проверяет статус страницы
		"""
	
	def element_properti(self, selector: SELECTOR, properti: str, displayed: bool, wait_timeout: TIMEOUT) -> tuple[str, list[T]]:
		"""
		Возвращает свойство одного элемента
		"""
	
	def elements_properti(self, selector: SELECTOR, properti: str, displayed: bool, wait_timeout: TIMEOUT) -> tuple[str, list[T]]:
		"""
		Возвращает свойство списка элементов элемента
		"""
	
	def vacuum(self):
		pass
	
	def close(self):
		"""
		Закрывает броузер
		"""
	
	@property
	def browser_version(self) -> str:
		"""
		Версия запущенного броузера
		"""
	
	@property
	def url(self) -> str:
		"""
		URL текущей страницы
		"""
	
	@property
	def title(self) -> str:
		"""
		Возвращает заголовок страницы
		"""
	
	@property
	def html(self) -> str:
		"""
		Возвращает исходный код страницы
		"""
	
	@property
	def test_uuid(self) -> str:
		"""
		Идентификатор теста
		"""
	
	@property
	def browser_name(self) -> str:
		"""
		Возвращаем наименование текущего броузера
		"""
	
	
