From 571f659b194e0163db5b50e221acb297a14a07fd Mon Sep 17 00:00:00 2001 From: Disco DeDisco Date: Sun, 8 Mar 2026 01:52:03 -0500 Subject: [PATCH] two new FTs, neither yet passing; test_wallet drives Stripe integration; test_gameboard drives Token system & apps.gameboard creation --- src/functional_tests/test_gameboard.py | 93 ++++++++++++++++ src/functional_tests/test_wallet.py | 148 +++++++++++++++++++++++++ 2 files changed, 241 insertions(+) create mode 100644 src/functional_tests/test_gameboard.py create mode 100644 src/functional_tests/test_wallet.py diff --git a/src/functional_tests/test_gameboard.py b/src/functional_tests/test_gameboard.py new file mode 100644 index 0000000..cd3e72f --- /dev/null +++ b/src/functional_tests/test_gameboard.py @@ -0,0 +1,93 @@ +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.common.by import By + +from .base import FunctionalTest + + +class GameboardNavigationTest(FunctionalTest): + def test_footer_links_to_gameboard(self): + # 1. Log in, nav to dashboard + self.create_pre_authenticated_session("capman@test.io") + self.browser.get(self.live_server_url) + # 2. Assert footer nav present w. dash- & gameboard tabs + self.browser.find_element(By.ID, "id_footer_nav") + self.browser.find_element(By.CSS_SELECTOR, '#id_footer_nav a[href="/"]') + self.browser.find_element(By.CSS_SELECTOR, '#id_footer_nav a[href="/gameboard/"]') + # 3. Click the gameboard tab + self.browser.find_element( + By.CSS_SELECTOR, '#id_footer_nav a[href="/gameboard/"]' + ).click() + # 4. Assert user landed on gameboard + self.wait_for( + lambda: self.assertRegex(self.browser.current_url, r"/gameboard/$") + ) + + def test_gameboard_shows_game_applets(self): + # 1. Log in, nav directly to gameboard + self.create_pre_authenticated_session("capman@test.io") + self.browser.get(self.live_server_url + "/gameboard/") + # 2. Assert My Games applet present + self.wait_for( + lambda: self.browser.find_element(By.ID, "id_applet_my_games") + ) + # 3. Assert no games listed yet for new user + my_games = self.browser.find_element(By.ID, "id_applet_my_games") + game_items = my_games.find_elements(By.CSS_SELECTOR, ".game-item") + self.assertEqual(len(game_items), 0) + # 4. Assert New Game applet present + self.browser.find_element(By.ID, "id_applet_new_game") + + def test_game_kit_panel_shows_token_inventory(self): + # 1. Log in, nav to gameboard + self.create_pre_authenticated_session("capman@test.io") + self.browser.get(self.live_server_url + "/gameboard/") + # 2. Assert game kit & gear btns both present (stacked vertically) + self.wait_for( + lambda: self.browser.find_element(By.ID, "id_game_kit_btn") + ) + self.browser.find_element(By.ID, "id_game_gear") + # 3. Click game kit btn to open panel + self.browser.find_element(By.ID, "id_game_kit_btn").click() + # 4. Wait for game kit panel to become visible + self.wait_for( + lambda: self.assertTrue( + self.browser.find_element(By.ID, "id_game_kit").is_displayed() + ) + ) + # 5. Assert Coin-on-a-String present in kit + coin = self.browser.find_element(By.ID, "id_kit_coin_on_a_string") + # 6. Hover over it; assert tooltip shows name, entry text & reuse description + ActionChains(self.browser).move_to_element(coin).perform() + self.wait_for( + lambda: self.assertTrue( + self.browser.find_element( + By.CSS_SELECTOR, "#id_kit_coin_on_a_string .token-tooltip" + ).is_displayed() + ) + ) + coin_tooltip = self.browser.find_element( + By.CSS_SELECTOR, "#id_kit_coin_on_a_string .token-tooltip" + ).text + self.assertIn("Coin-on-a-String", coin_tooltip) + self.assertIn("Admit 1 Entry", coin_tooltip) + self.assertIn("and another after that", coin_tooltip) + # 7. Assert 1× Free Token (complimentary) present in kit + free_token = self.browser.find_element(By.ID, "id_kit_free_token_0") + # 8. 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.CSS_SELECTOR, "#id_kit_free_token_0 .token-tooltip" + ).is_displayed() + ) + ) + free_tooltip = self.browser.find_element( + By.CSS_SELECTOR, "#id_kit_free_token_0 .token-tooltip" + ).text + self.assertIn("Free Token", free_tooltip) + self.assertIn("Admit 1 Entry", free_tooltip) + self.assertIn("Expires", free_tooltip) + # 9. Assert card deck & dice set placeholder present + self.browser.find_element(By.ID, "id_kit_card_deck") + self.browser.find_element(By.ID, "id_kit_dice_set") diff --git a/src/functional_tests/test_wallet.py b/src/functional_tests/test_wallet.py new file mode 100644 index 0000000..c3470b9 --- /dev/null +++ b/src/functional_tests/test_wallet.py @@ -0,0 +1,148 @@ +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.common.by import By + +from .base import FunctionalTest +from apps.dashboard.models import Applet + + +class WalletDisplayTest(FunctionalTest): + def setUp(self): + super().setUp() + Applet.objects.get_or_create(slug="wallet", defaults={"name": "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.CSS_SELECTOR, "#id_coin_on_a_string .token-tooltip" + ).is_displayed() + ) + ) + coin_tooltip = self.browser.find_element( + By.CSS_SELECTOR, "#id_coin_on_a_string .token-tooltip" + ).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_0") + # 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.CSS_SELECTOR, "#id_free_token_0 .token-tooltip" + ).is_displayed() + ) + ) + free_tooltip = self.browser.find_element( + By.CSS_SELECTOR, "#id_free_token_0 .token-tooltip" + ).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) + # 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="ZIP"]' + ).send_keys("42424") + # 6. Return to main doc & submit form + self.browser.switch_to.default_content() + 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 + self.wait_for( + 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