import time from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait class TradingLoginLocator: username = "txtUserID" password = "txtPwd" captcha_input = ( "//input[" "contains(@placeholder,'Capt') " "or contains(@placeholder,'capt') " "or contains(@id,'Captcha') " "or contains(@name,'Captcha')" "]" ) login_button = "loginButtonLink" class TradingMemberLoginLocator: username = "uname" username_continue_button = "submit_user" password = "password" captcha_input = "InputCaptcha" password_continue_button = "submit_password" class McoLoginLocator: form = "loginform" username = "#loginform input:not([type='hidden']):not([type='password'])" password = "#loginform input[type='password']" sign_in_button = "#loginform button[type='submit']" def login_to_trading_application(driver, username, password, timing, login_role="exchange"): if login_role == "trading_member": return login_to_trading_member_application(driver, username, password, timing) return login_to_exchange_application(driver, username, password, timing) def login_to_exchange_application(driver, username, password, timing): wait = WebDriverWait(driver, 20) username_field = wait.until( EC.visibility_of_element_located((By.ID, TradingLoginLocator.username)) ) username_field.clear() username_field.send_keys(username) password_field = wait.until( EC.visibility_of_element_located((By.ID, TradingLoginLocator.password)) ) password_field.clear() password_field.send_keys(password) wait.until( EC.visibility_of_element_located((By.XPATH, TradingLoginLocator.captcha_input)) ) captcha_wait_seconds = timing.get("login_captcha_wait_seconds", 10) print(f"Enter trading captcha manually within {captcha_wait_seconds} seconds...") time.sleep(captcha_wait_seconds) login_button = wait.until( EC.element_to_be_clickable((By.ID, TradingLoginLocator.login_button)) ) login_button.click() post_submit_wait_seconds = timing.get("login_post_submit_wait_seconds", 10) time.sleep(post_submit_wait_seconds) def login_to_trading_member_application(driver, username, password, timing): wait = WebDriverWait(driver, 20) username_field = wait.until( EC.visibility_of_element_located((By.ID, TradingMemberLoginLocator.username)) ) username_field.clear() username_field.send_keys(username) username_continue_button = wait.until( EC.element_to_be_clickable((By.ID, TradingMemberLoginLocator.username_continue_button)) ) username_continue_button.click() password_field = wait.until( EC.visibility_of_element_located((By.ID, TradingMemberLoginLocator.password)) ) password_field.clear() password_field.send_keys(password) wait.until( EC.visibility_of_element_located((By.ID, TradingMemberLoginLocator.captcha_input)) ) captcha_wait_seconds = timing.get("login_captcha_wait_seconds", 10) print(f"Enter trading member captcha manually within {captcha_wait_seconds} seconds...") time.sleep(captcha_wait_seconds) password_continue_button = wait.until( EC.element_to_be_clickable((By.ID, TradingMemberLoginLocator.password_continue_button)) ) password_continue_button.click() post_submit_wait_seconds = timing.get("login_post_submit_wait_seconds", 10) time.sleep(post_submit_wait_seconds) def login_to_mco_application(driver, username, password, timing): if not username or not password: raise ValueError("Configure users.mco.username and users.mco.password in config/runtime.json.") wait = WebDriverWait(driver, 20) wait.until(EC.presence_of_element_located((By.ID, McoLoginLocator.form))) username_field = wait.until( EC.visibility_of_element_located((By.CSS_SELECTOR, McoLoginLocator.username)) ) username_field.clear() username_field.send_keys(username) password_field = wait.until( EC.visibility_of_element_located((By.CSS_SELECTOR, McoLoginLocator.password)) ) password_field.clear() password_field.send_keys(password) sign_in_button = wait.until( EC.element_to_be_clickable((By.CSS_SELECTOR, McoLoginLocator.sign_in_button)) ) sign_in_button.click() wait.until(EC.url_contains("/Dashboard/")) wait.until( EC.visibility_of_element_located( (By.XPATH, "//*[self::a or self::h1 or self::h2 or self::div][normalize-space()='Dashboard']") ) ) post_submit_wait_seconds = timing.get("login_post_submit_wait_seconds", 10) time.sleep(post_submit_wait_seconds)