import time from django.contrib.staticfiles.testing import StaticLiveServerTestCase from selenium.webdriver.firefox.webdriver import WebDriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import Select from selenium.webdriver.support.expected_conditions import presence_of_element_located from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import NoSuchElementException from django.conf import settings from django.utils import timezone from datetime import timedelta from lambdainst.models import User from payments.models import Payment, Subscription class BaseOnlineTest(StaticLiveServerTestCase): # using a fixed port because you're supposed to forward a public ip to it # for the web hooks # $ ssh relaybox -R 12345:127.0.0.1:8000 # (set ROOT_URL to the right public url and RUN_ONLINE_TESTS to True) port = 8000 @classmethod def setUpClass(cls): super().setUpClass() cls.selenium = WebDriver(firefox_binary="/usr/bin/firefox") cls.selenium.implicitly_wait(12) cls.root_url = settings.ROOT_URL cls.wait = WebDriverWait(cls.selenium, 20) @classmethod def tearDownClass(cls): cls.selenium.quit() super().tearDownClass() def _signup(self): self.selenium.get("%s%s" % (self.root_url, "/account/signup")) username_input = self.selenium.find_element_by_name("username") username_input.send_keys("test-user") password_input = self.selenium.find_element_by_name("password") password_input.send_keys("test-password") password_input = self.selenium.find_element_by_name("password2") password_input.send_keys("test-password") self.selenium.find_element_by_xpath('//input[@value="Sign up"]').click() def wait(f, initial=3, between=2): time.sleep(initial) print("waiting for confirmation...") while True: try: f() break except (NoSuchElementException, AssertionError) as exc: print(f"confirmation text not found ({exc!r})") time.sleep(between) class OnlineStripeTests(BaseOnlineTest): fixtures = [] def test_payment(self): self._signup() self.selenium.find_element_by_xpath('//label[@for="tab_onetime"]').click() self.wait.until( EC.visibility_of( self.selenium.find_element_by_xpath( '//label[@for="tab_onetime"]/..//select[@name="payment-method"]' ) ) ) self.selenium.find_element_by_xpath( '//label[@for="tab_onetime"]/..//select[@name="plan"]/option[@value="3m"]' ).click() self.selenium.find_element_by_xpath( '//label[@for="tab_onetime"]/..//select[@name="payment-method"]/option[@value="stripe"]' ).click() self.selenium.find_element_by_xpath( '//label[@for="tab_onetime"]/..//input[@value="Buy Now"]' ).click() assert self.selenium.find_element_by_xpath('//span[text()="Test Mode"]') self.selenium.find_element_by_xpath('//input[@name="email"]').send_keys( "test@ccrypto.org" ) self.selenium.find_element_by_xpath('//input[@name="cardNumber"]').send_keys( "4242424242424242" ) self.selenium.find_element_by_xpath('//input[@name="cardExpiry"]').send_keys( "6/66" ) self.selenium.find_element_by_xpath('//input[@name="cardCvc"]').send_keys("420") self.selenium.find_element_by_xpath('//input[@name="billingName"]').send_keys( "Test User" ) self.selenium.find_element_by_xpath('//button[@type="submit"]').click() self.wait.until( EC.presence_of_element_located((By.XPATH, '//*[contains(text(), "Waiting for payment")]')) ) def check_active(): # refresh payment as we dont have a worker p = Payment.objects.order_by('id').first() p.refresh() self.selenium.refresh() self.selenium.find_element_by_xpath('//h2[contains(text(),"Confirmed")]') wait(check_active) user = User.objects.get(username="test-user") assert user.vpnuser.is_paid assert user.vpnuser.expiration >= (timezone.now() + timedelta(days=89)) def test_subscription(self): self._signup() self.selenium.find_element_by_xpath('//label[@for="tab_subscr"]').click() self.wait.until( EC.visibility_of( self.selenium.find_element_by_xpath( '//label[@for="tab_subscr"]/..//select[@name="payment-method"]' ) ) ) self.selenium.find_element_by_xpath( '//label[@for="tab_subscr"]/..//select[@name="plan"]/option[@value="12m"]' ).click() self.selenium.find_element_by_xpath( '//label[@for="tab_subscr"]/..//select[@name="payment-method"]/option[@value="stripe"]' ).click() self.selenium.find_element_by_xpath( '//label[@for="tab_subscr"]/..//input[@value="Subscribe"]' ).click() assert self.selenium.find_element_by_xpath('//span[text()="Test Mode"]') self.selenium.find_element_by_xpath('//input[@name="email"]').send_keys( "test@ccrypto.org" ) self.selenium.find_element_by_xpath('//input[@name="cardNumber"]').send_keys( "4242424242424242" ) self.selenium.find_element_by_xpath('//input[@name="cardExpiry"]').send_keys( "6/66" ) self.selenium.find_element_by_xpath('//input[@name="cardCvc"]').send_keys("420") self.selenium.find_element_by_xpath('//input[@name="billingName"]').send_keys( "Test User" ) self.selenium.find_element_by_xpath('//button[@type="submit"]').click() self.wait.until( EC.presence_of_element_located((By.XPATH, '//*[contains(text(), "Your subscription is processing.")]')) ) def check_active(): # refresh sub as we dont have a worker p = Subscription.objects.order_by('id').first() p.refresh() self.selenium.refresh() sub_status = self.selenium.find_element_by_xpath( '//td[text()="Subscription"]//following-sibling::td' ) assert sub_status.text.startswith("ACTIVE") wait(check_active) sub_status = self.selenium.find_element_by_xpath( '//td[text()="Subscription"]//following-sibling::td' ) assert sub_status.text.startswith("ACTIVE") user = User.objects.get(username="test-user") assert user.vpnuser.is_paid sub_status.find_element_by_xpath('a[text()="cancel"]').click() self.selenium.find_element_by_xpath( '//input[@value="Cancel Subscription"]' ).click() sub_status = self.selenium.find_element_by_xpath( '//td[text()="Subscription"]//following-sibling::td' ) assert not sub_status.text.startswith("ACTIVE") user = User.objects.get(username="test-user") assert user.vpnuser.is_paid assert not user.vpnuser.get_subscription()