*** Settings ***
Library SeleniumLibrary
Library OperatingSystem
Library String
Library DateTime
Suite Setup Suite Setup Tasks
Suite Teardown Close All Browsers
*** Variables ***
${URL} https://www.chase.com
${OUTPUTDIR} results
*** Test Cases ***
Login To Chase
[Documentation] Log in to Chase using environment variables for credentials.
Click Sign In
Input Username
Input Password
Submit Login
Wait For Account Dashboard
Get Checking Account Info
Get Credit Card Info
Save Account Data
*** Keywords ***
Suite Setup Tasks
Log Debug Variables
Open Browser To Chase
Log Debug Variables
${debug_pause}= Get Environment Variable DEBUG_PAUSE 0
Set Suite Variable ${DEBUG_PAUSE} ${debug_pause}
${username}= Get Environment Variable CHASE_USER
${password}= Get Environment Variable CHASE_PASS
Set Suite Variable ${USERNAME} ${username}
${pw_list}= Create List ${password}
Set Suite Variable ${PASSWORD_LIST} ${pw_list}
Run Keyword If '${USERNAME}' == '' Fail Environment variable CHASE_USER is not set
Run Keyword If '${PASSWORD}' == '' Fail Environment variable CHASE_PASS is not set
Log To Console DEBUG_PAUSE=${DEBUG_PAUSE}
Log DEBUG_PAUSE=${DEBUG_PAUSE} INFO
Log To Console USERNAME=${USERNAME}
Run Keyword If '${PASSWORD}' == '' Log To Console PASSWORD is empty
Run Keyword Unless '${PASSWORD}' == '' Log To Console PASSWORD is set
${profile_dir}= Get Environment Variable CHROME_USER_DATA_DIR ${EXECDIR}/${OUTPUTDIR}/chrome-profile
Set Suite Variable ${CHROME_USER_DATA_DIR} ${profile_dir}
Create Directory ${CHROME_USER_DATA_DIR}
Open Browser To Chase
Open Browser ${URL} chrome options=add_argument("--user-data-dir=${CHROME_USER_DATA_DIR}")
Maximize Browser Window
Wait Until Page Contains Element id=signin-button timeout=20s
Click Sign In
${clicked}= Run Keyword And Return Status Click Element id=signin-button
Run Keyword If '${clicked}' == 'False' Execute JavaScript var el=document.getElementById('signin-button'); if(el){el.click();}
Wait Until Element Is Visible xpath=//input[contains(@id,'user') or contains(@name,'user') or contains(@placeholder,'Username')] timeout=20s
Wait For Input
Input Username
${existing}= Get Value xpath=//input[contains(@id,'user') or contains(@name,'user') or contains(@placeholder,'Username')]
${existing}= Strip String ${existing}
Run Keyword If '${existing}' == '' Input Text xpath=//input[contains(@id,'user') or contains(@name,'user') or contains(@placeholder,'Username')] ${USERNAME}
Run Keyword If '${existing}' == '' Capture Page Screenshot ${OUTPUTDIR}/after_username.png
Wait For Input
Input Password
${pw_to_use}= Set Variable ${PASSWORD_LIST}[0]
Input Text xpath=//input[contains(@id,'pass') or contains(@name,'pass') or contains(@placeholder,'Password')] ${pw_to_use}
Capture Page Screenshot ${OUTPUTDIR}/after_password.png
Wait For Input
Click Remember Me
Wait For Input
Submit Login
Click Button xpath=//button[contains(., 'Sign in') or contains(., 'Sign In')]
Wait For Input
Wait For Account Dashboard
# Wait for the Bank accounts heading to appear
Wait Until Page Contains Element xpath=//div[@role='heading' and @aria-level='2' and text()='Bank accounts'] timeout=15s
Capture Page Screenshot ${OUTPUTDIR}/Dashboard.png
Wait For Input
Run Keyword If '${DEBUG_PAUSE}' == '1' Sleep 20s
Click Remember Me
${clicked}= Run Keyword And Return Status Click Element xpath=//input[@type='checkbox' and (contains(@id,'remember') or contains(@name,'remember') or contains(@aria-label,'Remember') or contains(@placeholder,'Remember') or contains(@data-testid,'remember'))]
Run Keyword If '${clicked}' == 'False' Click Element xpath=//label[contains(., 'Remember') or contains(., 'Remember me')]
Run Keyword If '${clicked}' == 'False' Execute JavaScript var el=document.querySelector("input[type='checkbox']"); if(el && (el.id.indexOf('remember')>-1 || el.name.indexOf('remember')>-1)){el.click();}
Get Checking Account Info
Wait For Input
# Extract all accounts from account tiles
${all_accounts}= Execute JavaScript return (function() { var accounts = []; var tiles = document.querySelectorAll('[data-testid="accountTile"]'); tiles.forEach(function(tile) { var btn = tile.querySelector('[data-testid="accounts-name-link"] mds-button'); var accountName = btn ? btn.getAttribute('text') || btn.textContent : 'N/A'; var dataItems = tile.querySelectorAll('[id*="dataItem"] [data-testid="dataItem-value"]'); var currentBalance = 'N/A'; var deposits = 'N/A'; var withdrawals = 'N/A'; dataItems.forEach(function(item) { var parent = item.closest('[id*="dataItem"]'); if (parent && parent.id.includes('availableBalance')) { currentBalance = item.textContent.trim(); } else if (parent && parent.id.includes('totalDeposits')) { deposits = item.textContent.trim(); } else if (parent && parent.id.includes('totalWithdrawals')) { withdrawals = item.textContent.trim(); } }); accounts.push({name: accountName, currentBalance: currentBalance, deposits: deposits, withdrawals: withdrawals}); }); return JSON.stringify(accounts); })();
Log To Console All Bank Accounts: ${all_accounts}
Set Suite Variable ${ALL_BANK_ACCOUNTS} ${all_accounts}
Capture Page Screenshot ${OUTPUTDIR}/bank_accounts.png
Get Credit Card Info
Wait For Input
# Extract all credit cards from card tiles - credit cards may have different structure
${credit_cards}= Execute JavaScript return (function() { var cards = []; var tiles = document.querySelectorAll('[class*="card"], [class*="credit-card"], [data-testid*="creditCard"]'); if (tiles.length === 0) { tiles = document.querySelectorAll('[class*="account-tile"]'); } tiles.forEach(function(tile) { var hasCurrentBalance = tile.querySelector('[id*="currentBalance-dataItem"]'); if (hasCurrentBalance) { var btn = tile.querySelector('[data-testid="accounts-name-link"] mds-button'); var cardName = btn ? btn.getAttribute('text') || btn.textContent : 'N/A'; var balanceEl = tile.querySelector('[id*="currentBalance-dataItem"] [data-testid="dataItem-value"]'); var currentBalance = balanceEl ? balanceEl.textContent.trim() : 'N/A'; var minPaymentEl = tile.querySelector('[id*="minimumPaymentAmount-dataItem"] [data-testid="dataItem-value"]'); var minimumPayment = minPaymentEl ? minPaymentEl.textContent.trim() : 'N/A'; var statementBalanceEl = tile.querySelector('[id*="statementBalance-dataItem"] [data-testid="dataItem-value"]'); var statementBalance = statementBalanceEl ? statementBalanceEl.textContent.trim() : 'N/A'; cards.push({name: cardName, currentBalance: currentBalance, minimumPayment: minimumPayment, statementBalance: statementBalance}); } }); return JSON.stringify(cards); })();
Log To Console All Credit Cards: ${credit_cards}
Set Suite Variable ${ALL_CREDIT_CARDS} ${credit_cards}
Capture Page Screenshot ${OUTPUTDIR}/credit_cards.png
Save Account Data
${timestamp}= Get Current Date result_format=%Y-%m-%d %H:%M:%S
${file_content}= Set Variable Account Data (${timestamp})\n\n=== BANK ACCOUNTS ===\n
${bank_accounts}= Evaluate json.loads("""${ALL_BANK_ACCOUNTS}""") json
FOR ${account} IN @{bank_accounts}
${file_content}= Catenate ${file_content} \n--- Account ---\nName: ${account}[name]\nCurrent Balance: ${account}[currentBalance]\nDeposits This Month: ${account}[deposits]\nWithdrawals This Month: ${account}[withdrawals]\n
END
${file_content}= Catenate ${file_content} \n\n=== CREDIT CARDS ===\n
${credit_cards}= Evaluate json.loads("""${ALL_CREDIT_CARDS}""") json
FOR ${card} IN @{credit_cards}
${file_content}= Catenate ${file_content} \n--- Credit Card ---\nName: ${card}[name]\nCurrent Balance: ${card}[currentBalance]\nMinimum Payment: ${card}[minimumPayment]\nStatement Balance: ${card}[statementBalance]\n
END
Create File ${OUTPUTDIR}/account_data.txt ${file_content}
Log To Console Account data saved to ${OUTPUTDIR}/account_data.txt
Log All accounts and credit cards extracted and saved INFO