Skip to content

Commit

Permalink
Merge pull request #6094 from emilghittasv/playwright-refactorization
Browse files Browse the repository at this point in the history
Playwright helper functions refactorization & test fixes
  • Loading branch information
emilghittasv committed Jul 1, 2024
2 parents 3422541 + 3d7bf8a commit fcf4819
Show file tree
Hide file tree
Showing 13 changed files with 305 additions and 167 deletions.
191 changes: 125 additions & 66 deletions playwright_tests/core/basepage.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import random
from typing import Union

from playwright.sync_api import Page, ElementHandle, Locator, TimeoutError


Expand All @@ -7,157 +9,214 @@ class BasePage:
def __init__(self, page: Page):
self._page = page

# Single locator retrieval.
# Waits for DOM load to finish.
def _get_element_locator(self, xpath: str) -> Locator:
self.__wait_for_dom_load_to_finnish()
def _get_element_locator(self, xpath: str, with_wait=True) -> Locator:
"""
This helper function returns the element locator from a given xpath.
"""
if with_wait:
self.__wait_for_dom_load_to_finnish()
return self._page.locator(xpath)

# Multiple locators retrieval.
# Waits for DOM load to finish.
def _get_elements_locators(self, xpath: str) -> list[Locator]:
"""
This helper function returns a list of element locators from a given xpath.
"""
self.__wait_for_dom_load_to_finnish()
return self._page.locator(xpath).all()

def _get_current_page_url(self) -> str:
"""
This helper function returns the current page URL.
"""
return self._page.url

# Single locator retrieval without wait.
def _get_element_locator_no_wait(self, xpath: str) -> Locator:
return self._page.locator(xpath)

# Element handle retrieval.
def _get_element_handles(self, xpath: str) -> list[ElementHandle]:
"""
This helper function returns a list of element handles from a given xpath.
"""
return self._get_element_locator(xpath).element_handles()

# Multiple element handles retrieval.
def _get_element_handle(self, xpath: str) -> ElementHandle:
"""
This helper function returns a single element handle from a given xpath.
"""
return self._get_element_locator(xpath).element_handle()

# Multiples elements inner text retrieval.
def _get_text_of_elements(self, xpath: str) -> list[str]:
"""
This helper function returns a list containing the inner texts of a given xpath.
"""
return self._get_element_locator(xpath).all_inner_texts()

# Element inner text retrieval.
def _get_text_of_element(self, xpath: str) -> str:
"""
This helper function returns the inner text of a given xpath.
"""
return self._get_element_locator(xpath).inner_text()

# Returning true if the inner text of an element is empty
def _is_element_empty(self, xpath: str) -> bool:
"""
This helper function returns checks if the given xpath has an inner text.
"""
return not self._get_element_locator(xpath).inner_text()

# Elements count retrieval.
def _get_elements_count(self, xpath: str) -> int:
"""
This helper function returns the web element count from a given xpath.
"""
return self._get_element_locator(xpath).count()

# Fetching a particular element attribute value.
def _get_element_attribute_value(self, xpath: str, attribute: str) -> str:
return self._get_element_locator(xpath).get_attribute(attribute)

# Fetch a particular element locator attribute value.
def _get_element_locator_attribute_value(self, locator: Locator, attribute: str) -> str:
self.__wait_for_dom_load_to_finnish()
return locator.get_attribute(attribute)

def _get_attribute_values_of_elements(self, locator: list[Locator],
attribute: str) -> list[str]:
self.__wait_for_dom_load_to_finnish()
values = []
for element in locator:
values.append(element.get_attribute(attribute))
return values
def _get_element_attribute_value(self, element: Union[str, Locator, list[Locator]],
attribute: str) -> Union[str, list[str]]:
"""
This helper function returns the given attribute of a given locator or web element.
"""
if isinstance(element, str):
return self._get_element_locator(element).get_attribute(attribute)
elif isinstance(element, list):
self.__wait_for_dom_load_to_finnish()
values = []
for element in element:
values.append(element.get_attribute(attribute))
return values
else:
return element.get_attribute(attribute)

def _wait_for_given_timeout(self, timeout: float):
"""
This helper function pauses the execution for a given timeout.
"""
self._page.wait_for_timeout(timeout)

# Fetching a particular element input value.
def _get_element_input_value(self, xpath: str) -> str:
"""
This helper function returns the input value of a given element locator.
"""
return self._get_element_locator(xpath).input_value()

# Get element inner text from page.
def _get_element_inner_text_from_page(self, xpath: str) -> str:
"""
This helper function returns the inner text of a given locator via the page instance.
"""
return self._page.inner_text(xpath)

# Get Element text content.
def _get_element_text_content(self, xpath: str) -> str:
"""
This helper function returns the text content of a given locator via the page instance.
"""
return self._page.text_content(xpath)

# Clicking on a particular element.
def _click(self, xpath: str):
self._wait_for_selector(xpath)
self._get_element_locator(xpath).click()
def _click(self, element: Union[str, Locator], with_wait=True):
"""
This helper function clicks on a given element locator.
"""
if isinstance(element, str):
if with_wait:
self._wait_for_selector(element)
self._get_element_locator(element).click()
elif isinstance(element, Locator):
element.click()

# Clicking on a particular element without wait.
def _click_without_wait(self, xpath: str):
self._get_element_locator_no_wait(xpath).click()
def _click_on_an_element_by_index(self, xpath: str, index: int):
"""
This helper function clicks on a given element locator based on a given index.
"""
self._get_element_locator(xpath).nth(index).click()

def _click_on_first_item(self, xpath: str):
"""
This helper function clicks on the first item from a given web element locator list.
"""
self._get_element_locator(xpath).first.click()

# Filling text to an element input.
def _fill(self, xpath: str, text: str):
"""
This helper function fills a given text inside a given element locator.
"""
self._get_element_locator(xpath).fill(text)

# Typing text inside an input field with a given delay.
def _type(self, xpath: str, text: str, delay: int):
"""
This helper function types a given string inside a given element locator with a given delay
"""
self._get_element_locator(xpath).type(text=text, delay=delay)

# Type inside an input field by pressing a particular key.
def _press_a_key(self, xpath: str, key: str):
"""
This helper function types a given key inside a given element locator.
"""
self._get_element_locator(xpath).press(key)

# Clearing an input field.
def _clear_field(self, xpath: str):
"""
This helper function clears the given element locator input field.
"""
self._get_element_locator(xpath).clear()

# Clicking on a particular element by index.
def _click_on_an_element_by_index(self, xpath: str, index: int):
self._get_element_locator(xpath).nth(index).click()

# Clicking on the first element from a locator list.
def _click_on_first_item(self, xpath: str):
self._get_element_locator(xpath).first.click()

# Choosing an option by label from a select element.
def _select_option_by_label(self, xpath: str, label_name: str):
"""
This helper function selects an element from a given select box based on label.
"""
self._get_element_locator(xpath).select_option(label=label_name)

# Choosing an option by value from a select element.
def _select_option_by_value(self, xpath: str, value: str):
"""
This helper function selects a element from a given select box based on value.
"""
self._get_element_locator(xpath).select_option(value=value)

# Selecting a random dropdown menu option by 'value'.
def _select_random_option_by_value(self, dropdown_locator: str, xpath_options: str):
"""
This helper function selects a random option from a given web element locator.
"""
elements = []
for element in self._get_elements_locators(xpath_options):
locator_value = self._get_element_locator_attribute_value(element, 'value')
locator_value = self._get_element_attribute_value(element, 'value')
if locator_value == '':
continue
else:
elements.append(locator_value)
self._select_option_by_value(dropdown_locator, random.choice(elements))

# Accept a dialog.
def _accept_dialog(self):
"""
This helper function accepts the displayed dialog.
"""
self._page.on("dialog", lambda dialog: dialog.accept())

# Hover over a particular element.
def _hover_over_element(self, xpath: str):
"""
This helper function performs a mouse-over action over a given element locator.
"""
self._get_element_locator(xpath).hover()

# Verifying if a particular element is visible.
def _is_element_visible(self, xpath: str) -> bool:
"""
This helper function checks if a given element locator is visible.
"""
return self._get_element_locator(xpath).is_visible()

# Verifying if a particular checkbox is checked.
def _is_checkbox_checked(self, xpath: str) -> bool:
"""
This helper function checks if a given element locator is checked.
"""
return self._get_element_locator(xpath).is_checked()

# Custom wait for DOM load to finish.
def __wait_for_dom_load_to_finnish(self):
"""
This helper function performs two waits:
1. Waits for the dom load to finish.
2. Waits for the load event to be fired when the whole page, including resources has loaded
"""
self._page.wait_for_load_state("domcontentloaded")
self._page.wait_for_load_state("load")

# Custom wait for selector to be displayed.
def _wait_for_selector(self, xpath: str):
def _wait_for_selector(self, xpath: str, timeout=3500):
"""
This helper function waits for a given element locator to be visible based on a given
timeout.
"""
try:
self._page.wait_for_selector(xpath, timeout=3500)
self._page.wait_for_selector(xpath, timeout=timeout)
except TimeoutError:
print(f"{xpath} is not displayed")
Loading

0 comments on commit fcf4819

Please sign in to comment.