Skip to content

Instantly share code, notes, and snippets.

@hjwp
Last active March 1, 2016 15:44
Show Gist options
  • Save hjwp/0945e1eec19c29d3fb2c to your computer and use it in GitHub Desktop.
Save hjwp/0945e1eec19c29d3fb2c to your computer and use it in GitHub Desktop.
class PayPalPages(object):
def __init__(self, test, browser):
self.test = test
self.browser = browser
@contextmanager
def reload_if_paypal_cannot_get(self):
yield
if "Cannot GET" in self.browser.get_body_text() or "File not found" in self.browser.get_body_text():
print "*" * 80
print "Refreshing because PayPal barfed"
print "*" * 80
self.browser.refresh()
self.test.wait_for(
lambda: "Cannot GET" not in self.browser.get_body_text() and "File not found" not in self.browser.get_body_text(),
"For PayPal to pull its head out of its ****",
timeout_seconds=20
)
def type_into_unreliable_paypal_field(self, field, text):
for retry in range(5):
field.clear()
field.send_keys(text)
time.sleep(1)
if field.get_attribute("value") == text:
break
self.test.assertEqual(field.get_attribute("value"), text)
def login_to_sandbox(self):
try:
with self.reload_if_paypal_cannot_get():
self.browser.get('https://www.paypal.com/')
self.browser.wait_for_body_text_to_contain("Log In")
try:
self.browser.get_element("link=Log In").click()
except NoSuchElementException:
self.browser.get_element("css=.header-buttons .btn-secondary").click()
self.browser.wait_for_element_presence("id=email")
## Wait for PayPal's JavaScript login code to load.
time.sleep(10)
self.type_into_unreliable_paypal_field(self.browser.get_element('id=email'), SANDBOX_LOGIN)
self.type_into_unreliable_paypal_field(self.browser.get_element('id=password'), SANDBOX_PASSWORD)
self.browser.get_element('id=password').send_keys(Keys.ENTER)
with self.reload_if_paypal_cannot_get():
self.browser.get('https://developer.paypal.com/')
def developer_site_to_load():
body_text = self.browser.get_body_text().lower()
if "cannot get" in body_text:
self.browser.refresh()
return False
if "paypal developer" in body_text:
return True
if "we recently reviewed your account" in body_text:
with self.reload_if_paypal_cannot_get():
self.browser.get('https://developer.paypal.com/')
return False
self.test.wait_for(
developer_site_to_load,
lambda: "PayPal site didn't let us log in. Content was {!r}".format(
self.browser.get_body_text()
),
timeout_seconds=60
)
except Exception, e:
print 'Exception logging in to sandbox'
traceback.print_exc()
try:
body_text = self.browser.get_body_text()
except:
body_text = 'UNABLE TO GET BODY TEXT'
raise RetryableFailureException('Error logging in to PayPal: %r\n%r' % (e, body_text))
def delete_marked_users(self, marker):
## Delete any left over buyer accounts for this country and builder
## We don't care too much it this fails because we'll get them next time
## and the uniqifier should prevent collisions
print "Waiting for JS to load"
time.sleep(10)
xpath = '//tr[starts-with(@id, "%s")]/td/input[contains(@class, "singleCB")]' % (marker,)
account_checkboxes = self.browser.find_elements_by_xpath(xpath)
print 'about to delete %d test users' % (len(account_checkboxes),)
delete_modal_locator = "css=#modal-dialog"
delete_button_modal_locator = "css=.modal-dialog .delete-button"
if len(account_checkboxes):
for page_retry in range(5):
try:
for checkbox in account_checkboxes:
checkbox.click()
self.browser.get_element('id=deleteAccount').click()
self.browser.wait_for_element_presence(delete_button_modal_locator)
self.browser.wait_for_element_visibility(delete_button_modal_locator)
break
except:
print "*" * 80
traceback.print_exc()
print "TRYING TO DELETE USERS AGAIN"
print "*" * 80
self.browser.back()
account_checkboxes = self.browser.find_elements_by_xpath(xpath)
for retry in range(5):
try:
self.browser.get_element(delete_button_modal_locator).click()
self.browser.wait_for_element_presence(delete_modal_locator, False)
break
except:
traceback.print_exc()
self.test.assertFalse(self.browser.is_element_present(delete_modal_locator))
def go_to_sandbox_accounts_page(self):
try:
with self.reload_if_paypal_cannot_get():
self.browser.get('https://developer.paypal.com/developer/accounts')
time.sleep(3)
except:
import traceback
traceback.print_exc()
print "*" * 80
self.browser.get_body_text()
print "*" * 80
raise
def create_new_buyer_account(self, marker, country):
self.go_to_sandbox_accounts_page()
self.browser.wait_for_element_presence('link=Create Account')
self.browser.get_element('link=Create Account').click()
# enter email and credit card first because sometimes the validation logic fails so hard that it breaks the
# page forever
if country == 'UK':
card_type = "Visa/Delta/Electron"
else:
card_type = "Visa"
successfully_selected_card = False
successfully_entered_email = False
for tries in range(10):
Select(
self.browser.get_element('id=selectCountry')
).select_by_visible_text(BUYERS[country]['test_country'])
try:
Select(
self.browser.get_element('id=ccType')
).select_by_visible_text(card_type)
successfully_selected_card = True
except (AssertionError, NoSuchElementException), e:
if country == "US":
print "*" * 30, "PayPal didn't give us the option of a valid credit card in the dropdown"
self.browser.wait_for_element_visibility("css=#paymentCardD", True)
self.browser.get_element("css=#paymentCardD").click()
successfully_selected_card = True
else:
self.browser.refresh()
print "*" * 30, "Had to refresh page because no credit cards"
continue
try:
try:
email_field = self.browser.get_element('id=primary_email_alias')
password_field = self.browser.get_element('id=password')
first_name_field = self.browser.get_element('id=first_name')
last_name_field = self.browser.get_element('id=last_name')
except:
try:
email_field = self.browser.get_element('id=email')
password_field = self.browser.get_element('id=defaultPwd')
first_name_field = self.browser.get_element('id=fname')
last_name_field = self.browser.get_element('id=lname')
except:
self.test.fail(
"Can't find user setup fields in in page with IDs: "
+ ", ".join(
ii.get_attribute('id') for ii in self.browser.find_elements_by_xpath('//*[@id]')
)
)
uniquifier = ''.join(random.choice(string.ascii_lowercase + string.digits) for x in range(10))
account_name = '%s_%s' % (marker, uniquifier)
account_email = '%[email protected]' % (account_name,)
self.type_into_unreliable_paypal_field(email_field, account_email)
self.browser.wait_for_element_presence("css=#emailValidMsg")
successfully_entered_email = True
except AssertionError:
self.browser.refresh()
print "*" * 30, "Had to refresh page because email fucked"
continue
if successfully_entered_email and successfully_selected_card:
break
if not successfully_selected_card:
raise RetryableFailureException(
"Could not find valid credit card in %r" % (
[option.text for option in Select(self.browser.get_element('id=ccType')).options],
)
)
if not successfully_entered_email:
raise RetryableFailureException("Could not get the email to validate")
self.type_into_unreliable_paypal_field(password_field, BUYERS[country]['password'])
self.type_into_unreliable_paypal_field(first_name_field, BUYERS[country]['name'].split()[0])
self.type_into_unreliable_paypal_field(last_name_field, BUYERS[country]['name'].split()[1])
try:
self.browser.wait_for_element_enabledness('css=#createBtn', True)
except AssertionError:
raise RetryableFailureException("Create button was disabled, argh!")
with self.browser.wait_for_page_to_load_in_chrome(timeout_seconds=60):
self.browser.get_element('css=#createBtn').click()
try:
with self.reload_if_paypal_cannot_get():
self.browser.wait_for_body_text_to_contain(account_email)
except Exception, e:
raise RetryableFailureException(
"PayPal: couldn't find %s: %s\n%s" % (account_email, self.browser.get_body_text(), e)
)
BUYERS[country]['email'] = account_email
with fabric_settings(server="darcachon.resolversystems.com", password=DARC_PASSWORD):
append('/etc/aliases', '%s: florence.paypal' % (account_name,))
def get_paypal_user_marker(self, country):
if SHORT_BUILDER_ID is None:
self.test.fail("Could not get short builder id for this " + BUILDER_ID)
return BUYERS[country]['test_country_prefix'] + '_' + SHORT_BUILDER_ID
def login_to_sandbox_and_create_buyer_account(self, country):
self.login_to_sandbox()
self.create_buyer_account(country)
def create_buyer_account(self, country):
self.go_to_sandbox_accounts_page()
# Give PayPal JS a chance to load
time.sleep(10)
marker = self.get_paypal_user_marker(country)
self.delete_marked_users(marker)
self.create_new_buyer_account(marker, country)
def wait_for_overlay_to_disappear(self):
try:
self.browser.wait_for_element_visibility(
'id=progressMeter',
False,
timeout_seconds=60
)
except NoSuchElementException:
raise RetryableFailureException("PayPal site broken: stupid 'waiting' overlay never appeared")
except AssertionError as e:
print e
raise RetryableFailureException("PayPal site broken: stupid 'waiting' overlay never went away")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment