from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By from .base import FunctionalTest from apps.applets.models import Applet class WalletDisplayTest(FunctionalTest): def setUp(self): super().setUp() Applet.objects.get_or_create(slug="wallet", defaults={"name": "Wallet"}) for slug, name, cols, rows in [ ("wallet-balances", "Wallet Balances", 3, 3), ("wallet-tokens", "Wallet Tokens", 3, 3), ("wallet-payment", "Payment Methods", 6, 2), ]: Applet.objects.get_or_create( slug=slug, defaults={"name": name, "grid_cols": cols, "grid_rows": rows, "context": "wallet"}, ) def test_new_user_wallet_shows_starting_balances(self): # 1. Log in as new user self.create_pre_authenticated_session("capman@test.io") # 2. Navigate to dashboard self.browser.get(self.live_server_url) # 3. Find wallet applet summary card self.wait_for( lambda: self.browser.find_element(By.ID, "id_applet_wallet") ) # 4. Click thru to full wallet page via manage link self.browser.find_element( By.CSS_SELECTOR, "#id_applet_wallet a.wallet-manage-link" ).click() # 5. Assert user landed on wallet page self.wait_for( lambda: self.assertRegex(self.browser.current_url, r"/dashboard/wallet/$") ) # 6. Assert writs balance shows 144 (complimentary bundle on signup) self.wait_for( lambda: self.assertEqual( "144", self.browser.find_element(By.ID, "id_writs_balance").text, ) ) # 7. Assert esteem balance shows 0 self.assertEqual( "0", self.browser.find_element(By.ID, "id_esteem_balance").text, ) # 8. Assert Coin-on-a-String token element present coin = self.browser.find_element(By.ID, "id_coin_on_a_string") # 9. Hover over it; assert tooltip appears w. name, entry text, 'no expiry' ActionChains(self.browser).move_to_element(coin).perform() self.wait_for( lambda: self.assertTrue( self.browser.find_element(By.ID, "id_tooltip_portal").is_displayed() ) ) coin_tooltip = self.browser.find_element(By.ID, "id_tooltip_portal").text self.assertIn("Coin-on-a-String", coin_tooltip) self.assertIn("Admit 1 Entry", coin_tooltip) self.assertIn("no expiry", coin_tooltip) # 10. Assert ×1 Free Token present (complimentary on signup) free_token = self.browser.find_element(By.ID, "id_free_token") # 11. Hover over it; assert tooltip shows name, entry text, expiry date ActionChains(self.browser).move_to_element(free_token).perform() self.wait_for( lambda: self.assertTrue( self.browser.find_element(By.ID, "id_tooltip_portal").is_displayed() ) ) free_tooltip = self.browser.find_element(By.ID, "id_tooltip_portal").text self.assertIn("Free Token", free_tooltip) self.assertIn("Admit 1 Entry", free_tooltip) self.assertIn("Expires", free_tooltip) def test_wallet_payment_section_renders(self): # 1. Log in, navigate directly to wallet page self.create_pre_authenticated_session("capman@test.io") self.browser.get(self.live_server_url + "/dashboard/wallet/") # 2. Assert saved payment methods section present self.wait_for( lambda: self.browser.find_element(By.ID, "id_payment_methods") ) # 3. Assert the add-payment-method button is visible self.browser.find_element(By.ID, "id_add_payment_method") # 4. Assert Stripe Payment Element mount point exists self.browser.find_element(By.ID, "id_stripe_payment_element") def test_user_can_save_a_payment_method(self): # 1. Log in, navigate to wallet page self.create_pre_authenticated_session("capman@test.io") self.browser.get(self.live_server_url + "/dashboard/wallet/") # 2. Click add-payment-method btn self.browser.find_element(By.ID, "id_add_payment_method").click() # 3. Wait for Stripe Payment Element iframe to appear inside mount point self.wait_for( lambda: self.browser.find_element( By.CSS_SELECTOR, "#id_stripe_payment_element iframe" ) ) # 4. Switch into Stripe iframe to interact w. card fields stripe_frame = self.browser.find_element( By.CSS_SELECTOR, "#id_stripe_payment_element iframe" ) self.browser.switch_to.frame(stripe_frame) # 4a. Wait for card inputs to render inside iframe self.wait_for( lambda: self.browser.find_element( By.CSS_SELECTOR, 'input[placeholder="1234 1234 1234 1234"]' ) ) # 5. Fill in Stripe test card details self.browser.find_element( By.CSS_SELECTOR, 'input[placeholder="1234 1234 1234 1234"]' ).send_keys("4242424242424242") self.browser.find_element( By.CSS_SELECTOR, 'input[placeholder="MM / YY"]' ).send_keys("12 / 26") self.browser.find_element( By.CSS_SELECTOR, 'input[placeholder="CVC"]' ).send_keys("424") self.browser.find_element( By.CSS_SELECTOR, 'input[placeholder="12345"]' ).send_keys("42424") # 6. Return to main doc & submit form self.browser.switch_to.default_content() self.wait_for( lambda: self.assertFalse( self.browser.find_element(By.ID, "id_save_payment_method").get_attribute("hidden") ) ) self.browser.find_element(By.ID, "id_save_payment_method").click() # 7. Wait for saved card to appear in payment methods list # Assert last 4 digits shown (Stripe confirmSetup + server round-trip can be slow) self.wait_for_slow( lambda: self.assertIn( "4242", self.browser.find_element(By.ID, "id_payment_methods").text, ) ) def test_user_can_purchase_tithe_token_bundle(self): # 1. Log in, navigate to wallet page self.create_pre_authenticated_session("capman@test.io") self.browser.get(self.live_server_url + "/dashboard/wallet/") # 2. Assert Tithe Token purchase section present self.wait_for( lambda: self.browser.find_element(By.ID, "id_tithe_token_shop") ) # 3. Assert min. +1 bundle option is visible bundle = self.browser.find_element( By.CSS_SELECTOR, "#id_tithe_token_shop .token-bundle" ) # 4. Assert ea. bundle shows token count & writ bonus placeholder self.assertIn("Tithe Token", bundle.text) self.assertIn("Writ", bundle.text) # 5. (Placeholder) Purchase flow via Stripe not driven in this FT: # Full charge assertion deferred until Stripe webhook handling implemented