import re from allure import step from assertpy import assert_that from playwright.sync_api import Page from playwright.sync_api import expect from src.helpers.logger import Logger class BaseUIElement: log = Logger() def __init__(self, page: Page, locator, name): self.page = page self.locator = locator self.name = name @property def _element(self): self.log.info(f"Getting '{self.name}' element by {self.locator}") element = self.page.locator(self.locator) return element @step("Check element '{0}' exists") def exists(self): self.log.info(f"Waiting for 1 element '{self.name}'") expect(self._element).to_have_count(1, timeout=20000) @step("Check element '{0}' does not exist") def not_exist(self): self.log.info(f"Waiting for 0 element '{self.name}'") expect(self._element).to_have_count(0, timeout=20000) def get_by(self, *args): self.log.info(f"Getting '{self.name}' element by parameters") return BaseUIElement(self.page, self.locator.format(*args), self.name) @step("Clicking '{0}'") def click(self, mouse_button=None,): self.log.info(f"Clicking an element {self.locator}") self._element.click(button=mouse_button) @step("Hover over '{0}'") def hover(self, position=None): self.log.info(f"Hovering an element {self.locator}") # box = self._element.bounding_box() # position = {'x': box["x"] + box["width"] * position[0], # 'y': box["y"] + box["height"] * position[1]} self._element.hover(position=position) @step("Input text {text} into {0}") def input_text(self, text): self.log.info(f"Filling with text='{text}' the {self.locator}") self._element.fill(text) @step("Is {0} enabled - {enabled}") def is_enabled(self, enabled): self.log.info(f"Does element {self.locator} NOT contain class - {enabled}") if enabled is True: expect(self._element).not_to_have_class(re.compile(r"disabled")) elif enabled is False: expect(self._element).to_have_class(re.compile(r"disabled")) @step("Is {0} selected - {selected}") def is_selected(self, selected): self.log.info(f"Does element {self.locator} contain class - {selected}") expect(self._element).not_to_have_class(re.compile(r"disabled")) if selected is True: expect(self._element).to_have_class(re.compile(r"selected")) else: expect(self._element).not_to_have_class(re.compile(r"selected")) @step("Is {0} selected - {state}") def is_data_selected(self, state): self.log.info(f"Check element's {self.locator} value for 'data-selected' class") if state is True: expect(self._element).to_have_attribute('data-selected', 'selected') else: expect(self._element).to_have_attribute('data-selected', 'not-selected') @step("{0} is active") def is_active(self): self.log.info(f"Does element {self.locator} contain class ") expect(self._element).to_have_class(re.compile(r"active")) @step("Is {0} hidden - {state}") def is_hidden(self, state): self.log.info(f"Does element {self.locator} have attribute ") expect(self._element).to_have_attribute("aria-hidden", str(state).lower()) @step("{0} has NO text {text}") def not_contain_text(self, text): expect(self._element).not_to_contain_text(text) @step("{0} has text {text}") def contain_text(self, text): print(self._element.inner_text()) self.log.info(f"Does element {self.locator} contain text '{text}'") try: expect(self._element).to_contain_text(text) except Exception: raise Exception(f'Actual text: {self._element.inner_text()}') @step("Retrieve text from the element {0}") def get_text(self): self.log.info(f"Return text content of the element {self.locator}") self._element.wait_for() return self._element.text_content() @step("Retrieve '{attribute}' attribute value from the element {0}") def get_attribute(self, attribute): self.log.info(f"Return attribute '{attribute}' of the element {self.locator}") return self._element.get_attribute(attribute) @step("Count number of elements {0}") def get_count(self): self.log.info(f"Return count of appeared element {self.locator}") return self._element.count() def __repr__(self): return self.name