diff --git a/payment/tests.py b/payment/tests.py index f665d67c..6ea46fd5 100644 --- a/payment/tests.py +++ b/payment/tests.py @@ -9,85 +9,114 @@ from django.test import TestCase from django.utils import unittest from django.conf import settings from regluit.payment.manager import PaymentManager -from regluit.payment.paypal import IPN, IPN_PAY_STATUS_ACTIVE, IPN_PAY_STATUS_COMPLETED, IPN_TXN_STATUS_COMPLETED, IPN_PAY_STATUS_COMPLETED, IPN_TXN_STATUS_COMPLETED -from noseselenium.cases import SeleniumTestCaseMixin from regluit.payment.models import Transaction from regluit.core.models import Campaign, Wishlist, Work -from django.contrib.auth.models import User from regluit.payment.parameters import * +from regluit.payment.paypal import * import traceback from django.core.validators import URLValidator from django.core.exceptions import ValidationError import time -from selenium import selenium, webdriver - +from selenium import webdriver +from selenium.webdriver.support.ui import WebDriverWait +import logging +import os from decimal import Decimal as D import datetime +def setup_selenium(): + # Set the display window for our xvfb + os.environ['DISPLAY'] = ':99' + +def set_test_logging(): + + # Setup debug logging to our console so we can watch + defaultLogger = logging.getLogger('') + defaultLogger.addHandler(logging.StreamHandler()) + defaultLogger.setLevel(logging.DEBUG) + + # Set the selenium logger to info + sel = logging.getLogger("selenium") + sel.setLevel(logging.INFO) + def loginSandbox(test, selenium): print "LOGIN SANDBOX" try: - selenium.open('https://developer.paypal.com/') - time.sleep(5) - test.failUnless(selenium.is_text_present('Member Log In')) - selenium.type('login_email', settings.PAYPAL_SANDBOX_LOGIN) - selenium.type('login_password', settings.PAYPAL_SANDBOX_PASSWORD) - time.sleep(2) - selenium.click('css=input[class=\"formBtnOrange\"]') - time.sleep(5) - test.failUnless(selenium.is_text_present('Test Accounts')) + selenium.get('https://developer.paypal.com/') + login_email = WebDriverWait(selenium, 10).until(lambda d : d.find_element_by_id("login_email")) + login_email.click() + login_email.send_keys(settings.PAYPAL_SANDBOX_LOGIN) + + login_password = WebDriverWait(selenium, 10).until(lambda d : d.find_element_by_id("login_password")) + login_password.click() + login_password.send_keys(settings.PAYPAL_SANDBOX_PASSWORD) + + submit_button = WebDriverWait(selenium, 10).until(lambda d : d.find_element_by_css_selector("input[class=\"formBtnOrange\"]")) + submit_button.click() + except: traceback.print_exc() -def authorizeSandbox(test, selenium, url): +def paySandbox(test, selenium, url, authorize=False): - print "AUTHORIZE SANDBOX" + if authorize: + print "AUTHORIZE SANDBOX" + else: + print "PAY SANDBOX" try: - selenium.open(url) - time.sleep(5) - test.failUnless(selenium.is_text_present('Your preapproved payment summary')) - selenium.click('loadLogin') - time.sleep(5) - selenium.type('id=login_email', settings.PAYPAL_BUYER_LOGIN) - selenium.type('id=login_password', settings.PAYPAL_BUYER_PASSWORD) - time.sleep(2) - selenium.click('submitLogin') - time.sleep(5) - test.failUnless(selenium.is_text_present('Review your information')) - selenium.click('submit.x') - time.sleep(10) - selenium.click('returnToMerchant') - time.sleep(15) + # We need this sleep to make sure the JS engine is finished from the sandbox loging page + time.sleep(20) + + selenium.get(url) + print "Opened URL %s" % url + + try: + # Button is only visible if the login box is NOT open + # If the login box is open, the email/pw fiels are already accessible + login_element = WebDriverWait(selenium, 30).until(lambda d : d.find_element_by_id("loadLogin")) + login_element.click() + + # This sleep is needed for js to slide the buyer login into view. The elements are always in the DOM + # so selenium can find them, but we need them in view to interact + time.sleep(20) + except: + print "Ready for Login" + + email_element = WebDriverWait(selenium, 60).until(lambda d : d.find_element_by_id("login_email")) + email_element.click() + email_element.send_keys(settings.PAYPAL_BUYER_LOGIN) + + password_element = WebDriverWait(selenium, 60).until(lambda d : d.find_element_by_id("login_password")) + password_element.click() + password_element.send_keys(settings.PAYPAL_BUYER_PASSWORD) + + submit_button = WebDriverWait(selenium, 60).until(lambda d : d.find_element_by_id("submitLogin")) + submit_button.click() + + # This sleep makes sure js has time to animate out the next page + time.sleep(20) + + final_submit = WebDriverWait(selenium, 60).until(lambda d : d.find_element_by_id("submit.x")) + final_submit.click() + + # This makes sure the processing of the final submit is complete + time.sleep(20) + + # Don't wait too long for this, it isn't really needed. By the time JS has gotten around to + # displaying this element, the redirect has usually occured + try: + return_button = WebDriverWait(selenium, 10).until(lambda d : d.find_element_by_id("returnToMerchant")) + return_button.click() + except: + blah = "blah" except: traceback.print_exc() - -def paySandbox(test, selenium, url): - print "PAY SANDBOX" - - try: - selenium.open(url) - time.sleep(5) - test.failUnless(selenium.is_text_present('Your payment summary')) - selenium.click('loadLogin') - time.sleep(5) - selenium.type('id=login_email', settings.PAYPAL_BUYER_LOGIN) - selenium.type('id=login_password', settings.PAYPAL_BUYER_PASSWORD) - time.sleep(2) - selenium.click('submitLogin') - time.sleep(5) - test.failUnless(selenium.is_text_present('Review your information')) - selenium.click('submit.x') - time.sleep(10) - selenium.click('returnToMerchant') - time.sleep(15) - - except: - traceback.print_exc() + print "Tranasction Complete" class PledgeTest(TestCase): @@ -96,9 +125,9 @@ class PledgeTest(TestCase): # This is an empty array where we will store any verification errors # we find in our tests - self.selenium = selenium("localhost", 4444, "*firefox", - "http://www.google.com/") - self.selenium.start() + setup_selenium() + self.selenium = webdriver.Firefox() + set_test_logging() def validateRedirect(self, t, url, count): @@ -107,7 +136,7 @@ class PledgeTest(TestCase): self.assertEqual(t.receiver_set.all().count(), count) self.assertEqual(t.receiver_set.all()[0].amount, t.amount) self.assertEqual(t.receiver_set.all()[0].currency, t.currency) - # self.assertNotEqual(t.reference, None) + # self.assertNotEqual(t.ref1Gerence, None) self.assertEqual(t.error, None) self.assertEqual(t.status, IPN_PAY_STATUS_CREATED) @@ -131,6 +160,9 @@ class PledgeTest(TestCase): loginSandbox(self, self.selenium) paySandbox(self, self.selenium, url) + + # sleep to make sure the transaction has time to complete + time.sleep(10) # by now we should have received the IPN # right now, for running on machine with no acess to IPN, we manually update statuses @@ -181,7 +213,7 @@ class PledgeTest(TestCase): self.validateRedirect(t, url, 1) def tearDown(self): - self.selenium.stop() + self.selenium.quit() class AuthorizeTest(TestCase): @@ -190,9 +222,9 @@ class AuthorizeTest(TestCase): # This is an empty array where we will store any verification errors # we find in our tests - self.selenium = selenium("localhost", 4444, "*firefox", - "http://www.google.com/") - self.selenium.start() + setup_selenium() + self.selenium = webdriver.Firefox() + set_test_logging() def validateRedirect(self, t, url): @@ -221,7 +253,7 @@ class AuthorizeTest(TestCase): self.validateRedirect(t, url) loginSandbox(self, self.selenium) - authorizeSandbox(self, self.selenium, url) + paySandbox(self, self.selenium, url, authorize=True) # stick in a getStatus to update statuses in the absence of IPNs p.checkStatus() @@ -231,7 +263,7 @@ class AuthorizeTest(TestCase): self.assertEqual(t.status, IPN_PAY_STATUS_ACTIVE) def tearDown(self): - self.selenium.stop() + self.selenium.quit() class TransactionTest(TestCase): def setUp(self): @@ -269,4 +301,4 @@ def suite(): suites = unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(testcase) for testcase in testcases]) return suites - \ No newline at end of file + diff --git a/selenium/INSTALL b/selenium/INSTALL new file mode 100644 index 00000000..1f3b9e8b --- /dev/null +++ b/selenium/INSTALL @@ -0,0 +1,20 @@ +Instructions to install xvfb + jdk + +1) sudo apt-get install openjdk-6-jre-headless +2) sudo apt-get install xfonts-base xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic +3) sudo apt-get install xvfb +4) sudo apt-get install firefox +5) sudo cp xvfb /etc/init.d/xvfb +6) sudo chmod 755 /etc/init.d/xvfb +7) sudo cp selenium /etc/init.d/selenium +8) sudo chmod 755 /etc/init.d/selenium + +Instructions to manually restart xvfb + selenium server + +1) sh /opt/regluit/selenium/start.sh + +Create a link to auto start xvfb+selenium on startup + +1) sudo ln -s /etc/init.d/xvfb /etc/rc2.d/S66xvfb +2) sudo ln -s /etc/init.d/selenium /etc/rc2.d/S67selenium + diff --git a/selenium/selenium b/selenium/selenium new file mode 100644 index 00000000..39338b37 --- /dev/null +++ b/selenium/selenium @@ -0,0 +1,15 @@ +if [ -z "$1" ]; then +echo "`basename $0` {start|stop}" +exit +fi + +case "$1" in +start) +export DISPLAY=:99 +java -jar /opt/regluit/selenium/selenium-server-standalone-2.5.0.jar > /opt/regluit/logs/selenium-rc.log 2>&1 & +;; + +stop) +killall java +;; +esac diff --git a/selenium-server-standalone-2.5.0.jar b/selenium/selenium-server-standalone-2.5.0.jar similarity index 100% rename from selenium-server-standalone-2.5.0.jar rename to selenium/selenium-server-standalone-2.5.0.jar diff --git a/selenium/start.sh b/selenium/start.sh new file mode 100644 index 00000000..ae40a412 --- /dev/null +++ b/selenium/start.sh @@ -0,0 +1,7 @@ +sudo /etc/init.d/xvfb stop +sudo /etc/init.d/selenium stop + +sudo /etc/init.d/xvfb start +sudo /etc/init.d/selenium start + + diff --git a/selenium/xvfb b/selenium/xvfb new file mode 100644 index 00000000..8df6c50a --- /dev/null +++ b/selenium/xvfb @@ -0,0 +1,14 @@ +if [ -z "$1" ]; then +echo "`basename $0` {start|stop}" +exit +fi + +case "$1" in +start) +/usr/bin/Xvfb :99 -ac -screen 0 2048x2048x8 & +;; + +stop) +killall Xvfb +;; +esac