Skip to content

Commit

Permalink
Add UI locators and utility functions for login automation
Browse files Browse the repository at this point in the history
Signed-off-by: nrao <[email protected]>
  • Loading branch information
NamrathaRao24 committed Jan 6, 2025
1 parent 898bae6 commit 65726e1
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
66 changes: 66 additions & 0 deletions ceph/UI/config/login.yaml
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']"
54 changes: 54 additions & 0 deletions ceph/UI/ids.py
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}.")
39 changes: 39 additions & 0 deletions ceph/UI/utilities.py
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}")

0 comments on commit 65726e1

Please sign in to comment.