Initial commit - Selenium automation framework
This commit is contained in:
@@ -0,0 +1,272 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
|
||||
REGRESSION_CONFIG_DIR = PROJECT_ROOT / "config"
|
||||
RUNTIME_CONFIG_PATH = REGRESSION_CONFIG_DIR / "runtime.json"
|
||||
|
||||
|
||||
def _load_json(path):
|
||||
|
||||
with path.open("r", encoding="utf-8") as file:
|
||||
return json.load(file)
|
||||
|
||||
|
||||
def load_runtime_config():
|
||||
|
||||
return _load_json(RUNTIME_CONFIG_PATH)
|
||||
|
||||
|
||||
def load_users_config():
|
||||
|
||||
runtime_config = load_runtime_config()
|
||||
users_config = runtime_config.get("users")
|
||||
|
||||
if not users_config:
|
||||
raise KeyError(f"Users config not found in {RUNTIME_CONFIG_PATH}.")
|
||||
|
||||
return users_config
|
||||
|
||||
|
||||
def load_product_config(product_family=None):
|
||||
|
||||
runtime_config = load_runtime_config()
|
||||
selected_product = product_family or runtime_config["execution"]["product_family"]
|
||||
product_config = runtime_config.get(selected_product)
|
||||
|
||||
if not product_config:
|
||||
product_config = runtime_config.get(selected_product.upper())
|
||||
|
||||
if not product_config:
|
||||
product_config = runtime_config.get(selected_product.lower())
|
||||
|
||||
if not product_config:
|
||||
raise KeyError(
|
||||
f"Product config not found for '{selected_product}' in {RUNTIME_CONFIG_PATH}."
|
||||
)
|
||||
|
||||
return product_config
|
||||
|
||||
|
||||
def _resolve_login(users_config, execution_config):
|
||||
|
||||
login_role = execution_config["login_role"]
|
||||
trading_member_key = execution_config.get("trading_member_key")
|
||||
|
||||
if login_role == "exchange":
|
||||
return users_config["exchange"]
|
||||
|
||||
if login_role == "trading_member":
|
||||
trading_member = users_config["trading_members"].get(trading_member_key)
|
||||
if not trading_member:
|
||||
raise KeyError(
|
||||
f"Trading member '{trading_member_key}' is not defined in {RUNTIME_CONFIG_PATH}"
|
||||
)
|
||||
return {
|
||||
"username": trading_member["username"],
|
||||
"password": trading_member["password"],
|
||||
"label": trading_member.get("label", trading_member_key),
|
||||
"member_id": trading_member.get("member_id", ""),
|
||||
"folder_upload_tm_ids": trading_member.get("folder_upload_tm_ids", []),
|
||||
}
|
||||
|
||||
raise ValueError(
|
||||
f"Unsupported login_role '{login_role}'. Use 'exchange' or 'trading_member'."
|
||||
)
|
||||
|
||||
|
||||
def _resolve_exchange_parallel_logins(users_config):
|
||||
|
||||
return [
|
||||
{
|
||||
"username": exchange_user["username"],
|
||||
"password": exchange_user["password"],
|
||||
"label": exchange_user.get("label", exchange_user["username"]),
|
||||
}
|
||||
for exchange_user in users_config.get("exchange_parallel", [])
|
||||
if exchange_user.get("username") and exchange_user.get("password")
|
||||
]
|
||||
|
||||
|
||||
def _resolve_trading_member_parallel_logins(users_config):
|
||||
|
||||
return [
|
||||
{
|
||||
"username": trading_member["username"],
|
||||
"password": trading_member["password"],
|
||||
"label": trading_member.get("label", trading_member_key),
|
||||
"key": trading_member_key,
|
||||
"member_id": trading_member.get("member_id", ""),
|
||||
"folder_upload_tm_ids": trading_member.get("folder_upload_tm_ids", []),
|
||||
}
|
||||
for trading_member_key, trading_member in users_config.get("trading_members", {}).items()
|
||||
if trading_member.get("username") and trading_member.get("password")
|
||||
]
|
||||
|
||||
|
||||
def _resolve_trading_member(users_config, execution_config):
|
||||
|
||||
trading_member_key = execution_config.get("trading_member_key")
|
||||
trading_member = users_config["trading_members"].get(trading_member_key)
|
||||
|
||||
if not trading_member:
|
||||
raise KeyError(
|
||||
f"Trading member '{trading_member_key}' is not defined in {RUNTIME_CONFIG_PATH}"
|
||||
)
|
||||
|
||||
return trading_member
|
||||
|
||||
|
||||
def _resolve_portal_urls(environment_config, execution_config):
|
||||
|
||||
active_environment = environment_config.get("active_environment")
|
||||
profiles = environment_config.get("portal_environments", {})
|
||||
profile = profiles.get(active_environment, {})
|
||||
pratyay_urls = profile.get("pratyay", {})
|
||||
login_role = execution_config["login_role"]
|
||||
|
||||
if profile:
|
||||
if not pratyay_urls.get(login_role):
|
||||
raise KeyError(
|
||||
f"Pratyay URL for role '{login_role}' is not configured in "
|
||||
f"environment.portal_environments.{active_environment}."
|
||||
)
|
||||
if not profile.get("mco"):
|
||||
raise KeyError(
|
||||
f"MCO URL is not configured in "
|
||||
f"environment.portal_environments.{active_environment}."
|
||||
)
|
||||
return {
|
||||
"environment": active_environment,
|
||||
"pratyay": pratyay_urls[login_role],
|
||||
"mco": profile["mco"],
|
||||
}
|
||||
|
||||
return {
|
||||
"environment": active_environment or "legacy",
|
||||
"pratyay": _resolve_application_url(environment_config, execution_config),
|
||||
"mco": "",
|
||||
}
|
||||
|
||||
|
||||
def _resolve_application_url(environment_config, execution_config):
|
||||
|
||||
login_role = execution_config["login_role"]
|
||||
role_urls = environment_config.get("login_urls", {})
|
||||
|
||||
if login_role in role_urls and role_urls[login_role]:
|
||||
return role_urls[login_role]
|
||||
|
||||
return environment_config["base_url"]
|
||||
|
||||
|
||||
def load_regression_config():
|
||||
|
||||
runtime_config = load_runtime_config()
|
||||
users_config = load_users_config()
|
||||
execution_config = runtime_config["execution"]
|
||||
product_config = load_product_config(execution_config["product_family"])
|
||||
active_selection = product_config.get("active_selection", {})
|
||||
defaults = product_config.get("defaults", {})
|
||||
|
||||
selected_product_code = execution_config.get(
|
||||
"product_code",
|
||||
active_selection.get("product_code", defaults["product_code"])
|
||||
)
|
||||
selected_trading_market = active_selection.get(
|
||||
"trading_market",
|
||||
defaults["trading_market"]
|
||||
)
|
||||
selected_trading_markets = active_selection.get("trading_markets", [])
|
||||
selected_bidding_screen = active_selection.get(
|
||||
"bidding_screen",
|
||||
defaults["bidding_screen"]
|
||||
)
|
||||
|
||||
trading_member = _resolve_trading_member(users_config, execution_config)
|
||||
login = _resolve_login(users_config, execution_config)
|
||||
portal_urls = _resolve_portal_urls(runtime_config["environment"], execution_config)
|
||||
|
||||
return {
|
||||
"url": portal_urls["pratyay"],
|
||||
"portal_urls": portal_urls,
|
||||
"login": login,
|
||||
"mco_login": users_config.get("mco", {}),
|
||||
"exchange_parallel_logins": _resolve_exchange_parallel_logins(users_config),
|
||||
"trading_member_parallel_logins": _resolve_trading_member_parallel_logins(users_config),
|
||||
"product": {
|
||||
"family": execution_config["product_family"],
|
||||
"product_type": defaults["product_type"],
|
||||
"product_code": selected_product_code,
|
||||
"trading_market": selected_trading_market,
|
||||
"trading_markets": selected_trading_markets,
|
||||
"bidding_screen": selected_bidding_screen
|
||||
},
|
||||
"execution": execution_config,
|
||||
"selected_role": execution_config["login_role"],
|
||||
"selected_flow": execution_config["flow_scope"],
|
||||
"selected_trading_member": trading_member,
|
||||
"timing": runtime_config["timing"],
|
||||
"available_product_codes": product_config.get("available_product_codes", []),
|
||||
"available_trading_markets": product_config.get("available_trading_markets", []),
|
||||
"available_bidding_screens": product_config.get("available_bidding_screens", []),
|
||||
"flows": product_config.get("flows", {}),
|
||||
"setup": product_config.get("setup", {}),
|
||||
"exchange_bidding": _normalize_bidding_config(product_config.get("bidding", {})),
|
||||
"exchange_matching": _normalize_matching_config(product_config.get("matching", {}))
|
||||
}
|
||||
|
||||
|
||||
def should_run_flow(flow_name):
|
||||
|
||||
selected_flow = load_regression_config()["selected_flow"]
|
||||
return selected_flow == "e2e" or selected_flow == flow_name
|
||||
|
||||
|
||||
def _normalize_bidding_config(raw_bidding_config):
|
||||
|
||||
if not raw_bidding_config:
|
||||
return {}
|
||||
|
||||
entry_method = raw_bidding_config.get("entry_method", {})
|
||||
data_paths = raw_bidding_config.get("data_paths", {})
|
||||
selection = raw_bidding_config.get("selection", {})
|
||||
timing = raw_bidding_config.get("timing", {})
|
||||
|
||||
return {
|
||||
**entry_method,
|
||||
**data_paths,
|
||||
**selection,
|
||||
**timing,
|
||||
"block_bid": entry_method.get("block_bid", raw_bidding_config.get("block_bid", {})),
|
||||
"excel_layout": raw_bidding_config.get("excel_layout", {}),
|
||||
"entries": raw_bidding_config.get("entries", [])
|
||||
}
|
||||
|
||||
|
||||
def _normalize_matching_config(raw_matching_config):
|
||||
|
||||
if not raw_matching_config:
|
||||
return {}
|
||||
|
||||
return {
|
||||
"matching_product_code": raw_matching_config.get("matching_product_code", ""),
|
||||
"matching_type": raw_matching_config.get("matching_type", ""),
|
||||
"source_types": raw_matching_config.get("source_types", []),
|
||||
"bid_transfer_markets": raw_matching_config.get(
|
||||
"bid_transfer_markets",
|
||||
["GDAM", "DAM", "HPDAM"]
|
||||
),
|
||||
"accepted_bid_transfer_statuses": raw_matching_config.get(
|
||||
"accepted_bid_transfer_statuses",
|
||||
["ACCEPTED", "PARTIALLY_ACCEPTED", "NO_BIDS"]
|
||||
),
|
||||
"initiation_mode": raw_matching_config.get("initiation_mode", ""),
|
||||
"portals": raw_matching_config.get("portals", {}),
|
||||
"download_folder_name": raw_matching_config.get("downloads", {}).get(
|
||||
"download_folder_name",
|
||||
"matching_files"
|
||||
),
|
||||
**raw_matching_config.get("timing", {})
|
||||
}
|
||||
Reference in New Issue
Block a user