-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add UI locators and utility functions for login automation
Signed-off-by: nrao <[email protected]>
- Loading branch information
1 parent
898bae6
commit 65726e1
Showing
3 changed files
with
159 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
pages: | ||
# Common locators for Sign In/Sign Up | ||
common: | ||
sign_in_button: | ||
locators: | ||
- xpath: "//button[contains(text(), 'Sign In')]" | ||
- id: "sign-in" | ||
sign_up_button: | ||
locators: | ||
- xpath: "//button[contains(text(), 'Sign Up')]" | ||
- id: "sign-up" | ||
|
||
# Page with username and password fields | ||
username_login: | ||
login_username: | ||
locators: | ||
- id: "username" | ||
- xpath: "//input[contains(@placeholder, 'username')]" | ||
login_password: | ||
locators: | ||
- id: "password" | ||
- xpath: "//input[contains(@placeholder, 'password')]" | ||
login_button: | ||
locators: | ||
- id: "submit" | ||
- xpath: "//button[contains(text(), 'Login')]" | ||
|
||
# Page with email and password fields (e.g., email-based login pages) | ||
email_login: | ||
login_username: | ||
locators: | ||
- name: "email" | ||
- xpath: "//input[@type='email']" | ||
login_password: | ||
locators: | ||
- name: "pass" | ||
- xpath: "//input[@type='password']" | ||
login_button: | ||
locators: | ||
- xpath: "//button[@type='submit']" | ||
sign_up_email: | ||
locators: | ||
- xpath: "//input[@type='email']" | ||
sign_up_password: | ||
locators: | ||
- xpath: "//input[@type='password']" | ||
sign_up_button: | ||
locators: | ||
- xpath: "//button[contains(text(), 'Register')]" | ||
|
||
# Example: Another page with unique locators | ||
custom_page: | ||
login_username: | ||
locators: | ||
- id: "user_field" | ||
- name: "username_field" | ||
- xpath: "//input[@id='user_field']" | ||
login_password: | ||
locators: | ||
- id: "pass_field" | ||
- name: "password_field" | ||
- xpath: "//input[@id='pass_field']" | ||
login_button: | ||
locators: | ||
- id: "login_submit" | ||
- xpath: "//button[@id='login_submit']" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import yaml | ||
from selenium.webdriver.common.by import By | ||
from selenium.webdriver.support import expected_conditions as EC | ||
from selenium.webdriver.support.ui import WebDriverWait | ||
|
||
|
||
class ElementIDs: | ||
def __init__(self, yaml_file_path: str): | ||
self.yaml_file_path = yaml_file_path | ||
self.elements = self._load_ids() | ||
|
||
def _load_ids(self) -> dict: | ||
try: | ||
with open(self.yaml_file_path, "r") as file: | ||
return yaml.safe_load(file) | ||
except FileNotFoundError: | ||
raise RuntimeError(f"YAML file not found: {self.yaml_file_path}") | ||
except yaml.YAMLError as e: | ||
raise RuntimeError(f"Error parsing YAML file: {e}") | ||
|
||
def get_element(self, key: str, driver, timeout: int = 10): | ||
keys = key.split(":") # Support nested keys | ||
section = self.elements | ||
for part in keys: | ||
section = section.get(part) | ||
if not section: | ||
raise KeyError(f"Key '{key}' not found in YAML file.") | ||
|
||
locators = section["locators"] | ||
for locator in locators: | ||
locator_type, locator_value = list(locator.items())[0] | ||
by_locator = self._get_by_locator(locator_type) | ||
try: | ||
return WebDriverWait(driver, timeout).until( | ||
EC.presence_of_element_located((by_locator, locator_value)) | ||
) | ||
except Exception: | ||
continue | ||
raise RuntimeError(f"Element '{key}' not found using provided locators.") | ||
|
||
def _get_by_locator(self, locator_type: str): | ||
locator_type = locator_type.lower() | ||
if locator_type == "id": | ||
return By.ID | ||
elif locator_type == "name": | ||
return By.NAME | ||
elif locator_type == "class": | ||
return By.CLASS_NAME | ||
elif locator_type == "xpath": | ||
return By.XPATH | ||
elif locator_type == "css": | ||
return By.CSS_SELECTOR | ||
else: | ||
raise ValueError(f"Unsupported locator type: {locator_type}.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from selenium.webdriver.common.by import By | ||
|
||
|
||
def read_table(driver, table_ref: str, locator_type: str = "id") -> list: | ||
""" | ||
Reads the data from a table on a webpage. | ||
:param driver: WebDriver instance. | ||
:param table_ref: The reference to locate the table (e.g., ID, class, XPath, etc.). | ||
:param locator_type: The type of locator ('id', 'name', 'class', 'xpath', 'css'). Defaults to 'id'. | ||
:return: A list of lists, where each sublist represents a row in the table. | ||
""" | ||
by_types = { | ||
"id": By.ID, | ||
"name": By.NAME, | ||
"class": By.CLASS_NAME, | ||
"xpath": By.XPATH, | ||
"css": By.CSS_SELECTOR, | ||
} | ||
|
||
if locator_type not in by_types: | ||
raise ValueError(f"Unsupported locator type: {locator_type}") | ||
|
||
try: | ||
|
||
table_element = driver.find_element(by_types[locator_type], table_ref) | ||
|
||
rows = table_element.find_elements(By.TAG_NAME, "tr") | ||
|
||
table_data = [] | ||
for row in rows: | ||
cells = row.find_elements(By.TAG_NAME, "td") | ||
if not cells: | ||
cells = row.find_elements(By.TAG_NAME, "th") | ||
row_data = [cell.text.strip() for cell in cells] | ||
table_data.append(row_data) | ||
|
||
return table_data | ||
except Exception as e: | ||
raise RuntimeError(f"Failed to read table with reference '{table_ref}': {e}") |