def link_account_via_plaid(self, plaid_username, plaid_password, bank: PlaidBank, account_type='checking'): """ Link a bank account to an Aspiration Product Account via Plaid """ # Switch to Privacy iframe IframeElement(self.driver, locators.PLAID_IFRAME).switch_to_iframe(start_at_default_content=True) BaseElement(self.driver, locators.PLAID_PRIVACY_CONTINUE_BUTTON).click() # Switch to Select Bank iframe IframeElement(self.driver, locators.PLAID_IFRAME).switch_to_iframe(start_at_default_content=True) TextElement(self.driver, locators.BANK_SEARCH_INPUT).set_text(bank.value) BaseElement(self.driver, locators.bank_option(bank.value)).click() # Switch to login iframe IframeElement(self.driver, locators.PLAID_IFRAME).switch_to_iframe(start_at_default_content=True) TextElement(self.driver, locators.PLAID_LOGIN_USER_ID_INPUT).set_text(plaid_username) TextElement(self.driver, locators.PLAID_LOGIN_PASSWORD_INPUT).set_text(plaid_password) BaseElement(self.driver, locators.PLAID_LOGIN_CONTINUE_BUTTON).click() # Switch to link account iframe IframeElement(self.driver, locators.PLAID_IFRAME).switch_to_iframe(start_at_default_content=True) if account_type is 'checking': BaseElement(self.driver, locators.PLAID_LINK_CHECKING_OPTION).click() elif account_type is 'savings': BaseElement(self.driver, locators.PLAID_LINK_SAVINGS_OPTION).click() else: raise ValueError(f"'{account_type}' is not a valid account_type value") BaseElement(self.driver, locators.PLAID_LINK_ACCOUNT_CONTINUE_BUTTON).click() self.driver.switch_to.default_content()
def submit_login(self, email, password): """ Submit credentials to attempt a user login """ self.wait_until_login_ready() TextElement(self.driver, locators.EMAIL_INPUT).set_text(email) TextElement(self.driver, locators.PASSWORD_INPUT).set_text(password) TextElement(self.driver, locators.PASSWORD_INPUT).send_keypress(Keys.RETURN)
def wait_until_login_ready(self): """ Wait for the login elements to display. Throw an exception if any do not display. """ TextElement(self.driver, locators.EMAIL_INPUT).wait_until_displayed() TextElement(self.driver, locators.PASSWORD_INPUT).wait_until_displayed() BaseElement(self.driver, locators.LOGIN_SUBMIT_BUTTON).wait_until_displayed()
def submit_plaid_account_numbers(self, routing_number, account_number): """ Submit new customer's Plaid routing number and account number """ IframeElement(self.driver, locators.PLAID_IFRAME).switch_to_iframe(start_at_default_content=True) TextElement(self.driver, locators.ROUTING_NUMBER_INPUT).set_text(routing_number) BaseElement(self.driver, locators.PLAID_LINK_ACCOUNT_CONTINUE_BUTTON).click() TextElement(self.driver, locators.ACCOUNT_NUMBER_INPUT).set_text(account_number) BaseElement(self.driver, locators.PLAID_LINK_ACCOUNT_CONTINUE_BUTTON).click() TextElement(self.driver, locators.ACCOUNT_NUMBER_INPUT).set_text(account_number) BaseElement(self.driver, locators.PLAID_LINK_ACCOUNT_CONTINUE_BUTTON).click() BaseElement(self.driver, locators.PLAID_SUCCESS_HEADER).wait_until_displayed() BaseElement(self.driver, locators.PLAID_LINK_ACCOUNT_CONTINUE_BUTTON).click() self.driver.switch_to.default_content()
def submit_credentials_to_google(self, email): """ Open google modal and submit email to sign in through google """ TextElement(self.driver, locators.GOOGLE_EMAIL_OR_PHONE_INPUT).set_text(email) BaseElement(self.driver, locators.GOOGLE_SIGN_IN_NEXT_BUTTON).click() BaseElement(self.driver, locators.OKTA_USERNAME_INPUT).wait_until_displayed() BaseElement(self.driver, locators.OKTA_PASSWORD_INPUT).wait_until_displayed() BaseElement(self.driver, locators.OKTA_SIGN_IN_BUTTON).wait_until_displayed()
def submit_new_account_credentials(self, email: str, password: str): """ Enter an email and password then submit the credentials """ BaseElement( self.driver, locators.TERMS_CHECKBOX_AGREEMENT_TEXT).wait_until_displayed() self.driver.get(construct_a_b_test_control_url( self.driver.current_url)) TextElement(self.driver, locators.EMAIL_INPUT).set_text(email) TextElement(self.driver, locators.PASSWORD_INPUT).set_text(password) BaseElement(self.driver, locators.TERMS_CHECKBOX_AGREEMENT_TEXT).click() BaseElement(self.driver, locators.TERMS_MODAL_SUBMIT_BUTTON).click() BaseElement(self.driver, locators.TERMS_MODAL).wait_until_not_displayed() BaseElement(self.driver, locators.SUBMIT_USER_CREDENTIALS_BUTTON).click()
def enter_pwif_amount(self, pwif_amount): """ Type a PWIF amount then submit the form""" TextElement(self.driver, locators.PWIF_OTHER_AMOUNT).set_text(pwif_amount) BaseElement(self.driver, locators.PWIF_NEXT_BUTTON).wait_until_displayed() BaseElement(self.driver, locators.PWIF_NEXT_BUTTON).click()
def submit_contact_details(self, customer_contact_details: dict): """ Complete and Submit the Contact Detail page :param customer_contact_details: a dictionary with the following keys: address, city, state, zipcode, phone """ if type(customer_contact_details) is not dict: raise TypeError( 'customer_info is expected to be a dictionary object. Type given was: {}' .format(type(customer_contact_details))) TextElement(self.driver, locators.PERMANENT_ADDRESS_INPUT).\ set_text(customer_contact_details['address_line_one']) TextElement(self.driver, locators.PERMANENT_ADDRESS_INPUT).send_keypress(Keys.TAB) TextElement(self.driver, locators.PERMANENT_CITY_INPUT).set_text( customer_contact_details['city']) TextElement(self.driver, locators.PERMANENT_STATE_INPUT).set_text( customer_contact_details['state']) TextElement(self.driver, locators.PERMANENT_ZIPCODE_INPUT).set_text( customer_contact_details['zipcode']) TextElement(self.driver, locators.PHONE_NUMBER_INPUT).click() TextElement(self.driver, locators.PHONE_NUMBER_INPUT).set_text( customer_contact_details['phone_number']) BaseElement(self.driver, locators.CONTACT_DETAILS_NEXT_BUTTON).click() BaseElement(self.driver, locators.VERIFY_ADDRESS_BUTTON).click() BaseElement(self.driver, locators.RYI_PAGE_TITLE).wait_until_displayed()
def submit_personal_info(self, customer_personal_info: dict): """ Complete and Submit the Personal Information page :param customer_personal_info: a dictionary that must have the following keys: first_name, last_name, date_of_birth, ssn """ if type(customer_personal_info) is not dict: raise TypeError( 'customer_info is expected to be a dictionary object. Type given was: {}' .format(type(customer_personal_info))) TextElement(self.driver, locators.DOB_INPUT).wait_until_displayed() TextElement(self.driver, locators.FIRST_NAME_INPUT).set_text( customer_personal_info['first_name']) TextElement(self.driver, locators.LAST_NAME_INPUT).click() TextElement(self.driver, locators.LAST_NAME_INPUT).set_text( customer_personal_info['last_name']) TextElement(self.driver, locators.DOB_INPUT).set_text( customer_personal_info['date_of_birth']) BaseElement(self.driver, locators.NEXT_BUTTON).click() BaseElement(self.driver, locators.DISABLED_NEXT_BUTTON).wait_until_displayed() TextElement(self.driver, locators.SSN_INPUT).set_text(customer_personal_info['ssn']) BaseElement(self.driver, locators.NEXT_BUTTON).click() TextElement(self.driver, locators.PERMANENT_ADDRESS_INPUT).wait_until_displayed()
def choose_recurring_deposit_options(self, opt_in=False): """ Submit the recurring deposit form or skip setting up a recurring deposit """ if opt_in: raise NotImplementedError else: BaseElement(self.driver, locators.NEXT_BUTTON).click() TextElement( self.driver, locators.RECURRING_DEPOSIT_TITLE).wait_until_not_displayed()
def get_login_status(self): """ Return the status of Login page """ login_page_displayed = TextElement(self.driver, locators.EMAIL_INPUT).displayed(3) error_message = BaseElement(self.driver, locators.ERROR_MESSAGE) if not login_page_displayed: return LoginStatus.NOT_AT_LOGIN_PAGE elif error_message.displayed(3): return self.get_error_message_status() else: return LoginStatus.NO_MESSAGE_PROMPT
def prepare_transfer(self, transfer_amount, from_account, to_account): """ Prepare a funds transfer with the specified details and advance to the scheduling step """ BaseElement(self.driver, locators.TRANSFER_MONEY_BUTTON).click() from_account_dropdown = BaseElement(self.driver, locators.FROM_ACCOUNT_DROP_DOWN) to_account_dropdown = BaseElement(self.driver, locators.TO_ACCOUNT_DROP_DOWN) from_account_dropdown.wait_until_displayed() to_account_dropdown.wait_until_displayed() from_account_dropdown.select_dropdown_value(from_account) to_account_dropdown.select_dropdown_value(to_account) TextElement(self.driver, locators.AMOUNT_INPUT).set_text(str(transfer_amount))
def prepare_transfer(self, transfer_amount, from_account, to_account): """ Prepare a funds transfer with the specified details and advance to the scheduling step """ BaseElement(self.driver, locators.INITIATE_TRANSFER_BUTTON).click() # Determine which aspiration account to use if to_account == TransfersPage.SPEND_ACCOUNT: BaseElement(self.driver, locators.CHOOSE_SPEND_BUTTON).click() withdraw = False elif to_account == TransfersPage.SAVE_ACCOUNT: BaseElement(self.driver, locators.CHOOSE_SAVE_BUTTON).click() withdraw = False elif from_account == TransfersPage.SPEND_ACCOUNT: BaseElement(self.driver, locators.CHOOSE_SPEND_BUTTON).click() withdraw = True elif from_account == TransfersPage.SAVE_ACCOUNT: BaseElement(self.driver, locators.CHOOSE_SAVE_BUTTON).click() withdraw = True else: raise ValueError( f"At least one of the accounts for a transfer must be one of: Save, Spend" ) # Dynamically generate account locator if withdraw: BaseElement(self.driver, locators.WITHDRAWAL_OUT_BUTTON).click() second_account_locator = BaseElement( self.driver, locators.account_picker(to_account)) else: second_account_locator = BaseElement( self.driver, locators.account_picker(from_account)) # Choose the 2nd bank BaseElement(self.driver, locators.CHOOSE_BANK_INPUT).click() second_account_locator.click() # Input amount in a way which activates the "Next Step" button amount = TextElement(self.driver, locators.AMOUNT_INPUT) amount.click() amount.set_text(str(transfer_amount)) self.driver.execute_script("mobile: performEditorAction", {'action': 'done'}) BaseElement(self.driver, locators.NEXT_STEP_BUTTON).click() # Ensure we've advanced to the scheduling activity BaseElement(self.driver, locators.PREVIEW_BUTTON).wait_until_displayed()
def submit_login(self, email, password): """ Submit credentials to attempt a user login """ self.wait_until_login_ready() TextElement(self.driver, locators.EMAIL_INPUT).set_text(email) TextElement(self.driver, locators.PASSWORD_INPUT).set_text(password) BaseElement(self.driver, locators.LOGIN_SUBMIT_BUTTON).click()
def submit_credentials_to_okta(self, username, password): """ Submit credentials to okta and attempt to login """ TextElement(self.driver, locators.OKTA_USERNAME_INPUT).set_text(username) TextElement(self.driver, locators.OKTA_PASSWORD_INPUT).set_text(password) BaseElement(self.driver, locators.OKTA_SIGN_IN_BUTTON).click() BaseElement(self.driver, locators.GOOGLE_ACCOUNT_VERIFICATION_TEXT).wait_until_displayed()
def wait_until_personal_info_displayed(self): """ Wait until the Personal Info page is displayed """ TextElement(self.driver, locators.DOB_INPUT).wait_until_displayed()
def prepare_buy_order(self, amount): """ Input amount of shares to purchase """ TextElement(self.driver, locators.INVESTMENT_ORDER_BUY_MODAL_AMOUNT).set_text( str(amount))
def submit_opening_deposit_amount(self, deposit_amount): """ Submit an opening deposit amount for the new product """ TextElement(self.driver, locators.DEPOSIT_INPUT).set_text(deposit_amount) BaseElement(self.driver, locators.NEXT_BUTTON).click()