示例#1
0
 def load(self):
     try:
         self.nav = NavigationFunctions(self.driver)
         self.load_body()
         self.menu = menu.SideMenu(self.driver)
         self.header = header.PrivateHeader(self.driver)
         return True
     except (NoSuchElementException, StaleElementReferenceException) as e:
         return False
示例#2
0
 def load(self):
     try:
         self.nav = NavigationFunctions(self.driver)
         self.load_body()
         self.header = header.PrivateHeader(self.driver)
         self.menu = menu.SideMenu(self.driver)
         if main.is_web() and main.is_ios():
             self.clear_ios_footer()
         return True
     except (NoSuchElementException, StaleElementReferenceException) as e:
         return False
示例#3
0
 def load(self):
     try:
         WDW(self.driver, 10).until(
             EC.element_to_be_clickable((By.CLASS_NAME, 'form-control')))
         self.nav = NavigationFunctions(self.driver)
         self.load_body()
         self.header = header.PubHeader(self.driver)
         self.footer = footer.PubFooter(self.driver)
         return True
     except (NoSuchElementException, StaleElementReferenceException) as e:
         return False
示例#4
0
 def load(self):
     try:
         # Make sure on map page
         WDW(self.driver, 10).until(lambda x: EC.element_to_be_clickable(
             (By.ID, 'busName')) and self.try_click('busName'))
         self.nav = NavigationFunctions(self.driver)
         self.load_body()
         self.menu = menu.SideMenu(self.driver)
         self.header = header.PrivateHeader(self.driver)
         return True
     except (NoSuchElementException, StaleElementReferenceException) as e:
         return False
 def load(self):
     try:
         self.nav = NavigationFunctions(self.driver)
         anchors = self.driver.find_elements_by_tag_name('a')
         if len(anchors) == 2:
             self.browserButton = anchors[0]
             self.appButton = anchors[1]
         else:
             raw_input(len(anchors))
         return True
     except (NoSuchElementException, StaleElementReferenceException,
             IndexError) as e:
         return False
示例#6
0
 def load(self):
     #raw_input('loading lobby page')
     try:
         self.nav = NavigationFunctions(self.driver)
         self.load_body()
         self.menu = menu.SideMenu(self.driver, True)
         self.header = header.PrivateHeader(self.driver)
         return True
     except (NoSuchElementException, StaleElementReferenceException,
             IndexError) as e:
         #print('Exception: ' + str(e))
         pass
     return False
示例#7
0
 def load(self):
     try:
         self.nav = NavigationFunctions(self.driver)
         self.header = header.PubHeader(self.driver)
         self.h2 = self.driver.find_element_by_tag_name('h2')
         # load continue button if normal, signin button if link is expired
         if self.h2.text == 'Oops!':
             self.load_expired_link()
         else:
             self.load_body()
         return True
     except (NoSuchElementException, StaleElementReferenceException,
             WebDriverException) as e:
         return False
class AddEmployeePage(Page):
    url_tail = 'add-employee'
    dynamic = False

    def load(self):
        try:
            self.nav = NavigationFunctions(self.driver)
            self.load_body()
            self.menu = menu.SideMenu(self.driver)
            self.header = header.PrivateHeader(self.driver)
            return True
        except (NoSuchElementException, StaleElementReferenceException,
                IndexError) as e:
            return False

    def load_body(self):
        self.form = self.driver.find_element_by_tag_name('form')
        find_by = self.form.find_elements_by_tag_name

        self.add_button = find_by('button')[0]
        self.inputs = {
            'first_name': find_by('input')[0],
            'last_name': find_by('input')[1],
            'employee_id': find_by('input')[2],
            'dob': find_by('input')[3],
            'zip_code': find_by('input')[4],
            'email': find_by('input')[5],
            'phone': find_by('input')[6],
        }

    def set_value(self, input_id, value):
        try:
            form_input = self.inputs[input_id]
            self.nav.set_input(form_input, value)
            # form_input.clear()
            # form_input.send_keys(value)
        except IndexError:
            raise Exception("Add Employee form: incorrect input index")

    def get_value(self, input_id):
        try:
            form_input = self.inputs[input_id]
            return form_input.get_attribute('value')
        except IndexError:
            raise Exception('Add Employee form: incorrect input index')

    def click_continue(self):
        self.nav.click_el(self.add_button)
        time.sleep(.4)
示例#9
0
    def load(self):
        try:
            self.nav = NavigationFunctions(self.driver)
            self.h1 = self.try_load_expired_header()
            # load continue button if normal, signin button if link is expired
            if self.h1 and self.h1.text == 'Oops!':
                self.load_expired_link()
            else:
                self.header = header.PubHeader(self.driver)
                self.load_body()

            return True
        except (NoSuchElementException, StaleElementReferenceException,
                IndexError) as e:
            return False
示例#10
0
class InvitePage(Page):
    url_tail = "/i/"  # i.e. https://ppay11.herokuapp.com/i/9acb52f3/934464476
    dynamic = True

    def load(self):
        try:
            self.nav = NavigationFunctions(self.driver)
            self.header = header.PubHeader(self.driver)
            self.h2 = self.driver.find_element_by_tag_name('h2')
            # load continue button if normal, signin button if link is expired
            if self.h2.text == 'Oops!':
                self.load_expired_link()
            else:
                self.load_body()
            return True
        except (NoSuchElementException, StaleElementReferenceException,
                WebDriverException) as e:
            return False

    def load_expired_link(self):
        """Invite has expired. Or error"""
        self.signin_button = self.driver.find_element_by_id('signin_button')

    def load_body(self):
        self.form = self.driver.find_element_by_tag_name('form')
        self.email_input = self.form.find_element_by_tag_name('input')
        self.continue_button = (
            self.form.find_element_by_class_name('primaryButton'))
        self.why_button = self.form.find_element_by_tag_name('a')

    def set_email(self, email):
        self.nav.set_input(self.email_input, email)

    def enter_email(self, email):
        self.set_email(email)
        self.click_continue()

    def get_email(self):
        return self.email_input.get_attribute('value')

    def click_why(self):
        self.nav.move_to_el(self.why_button)

    def click_continue(self):
        if self.h2.text == 'Oops!':  # (expired link)
            self.nav.move_to_el(self.signin_button)
        else:  # (normal link)
            self.nav.move_to_el(self.continue_button)

    def is_expired(self):
        """Return True if signin_button visible"""
        try:
            return self.signin_button.is_displayed()
        except Exception:
            return False
示例#11
0
 def load(self):
     try:
         WDW(self.driver, 10).until(
             lambda x: EC.presence_of_element_located(
                 (By.CLASS_NAME, 'sm-employee-table')) or EC.
             presence_of_element_located((By.CLASS_NAME, 'employeeDiv')))
         self.nav = NavigationFunctions(self.driver)
         self.load_body()
         if EmployeePage.debug:
             raw_input('1')
         self.header = header.PrivateHeader(self.driver)
         if EmployeePage.debug:
             raw_input('2')
         self.menu = menu.SideMenu(self.driver, True)
         return True
     except (NoSuchElementException, StaleElementReferenceException,
             IndexError) as e:
         return False
示例#12
0
 def load(self, expectedTab='send'):
     self.expected_tab = expectedTab
     self.nav = NavigationFunctions(self.driver)
     try:
         self.load_body()
         self.menu = menu.SideMenu(self.driver, True)
         self.header = header.PrivateHeader(self.driver)
         return True
     except (NoSuchElementException, StaleElementReferenceException,
             IndexError) as e:
         return False
class ForgotPasswordForm(Component):
    def __init__(self, driver):
        self.driver = driver
        self.nav = NavigationFunctions(self.driver)

    def load(self):
        WDW(self.driver, 10).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'resetPWForm')))
        self.form = self.driver.find_element_by_class_name('resetPWForm')
        self.email_input = self.form.find_element_by_id('login')
        self.continue_button = self.form.find_element_by_id('submit_button')
        return True

    def submit(self, email, submit):
        if email or email == '':
            self.set_email(email)
        if submit:
            self.nav.click_el(self.continue_button)

    def set_email(self, email):
        self.nav.set_input(self.email_input, email)
class InvitePreScreenPage(Page):
    def load(self):
        try:
            self.nav = NavigationFunctions(self.driver)
            anchors = self.driver.find_elements_by_tag_name('a')
            if len(anchors) == 2:
                self.browserButton = anchors[0]
                self.appButton = anchors[1]
            else:
                raw_input(len(anchors))
            return True
        except (NoSuchElementException, StaleElementReferenceException,
                IndexError) as e:
            return False

    def click(self, button='browser'):
        if button == 'browser':
            self.nav.click_el(self.browserButton)
        elif button == 'app':
            self.nav.click_el(self.appButton)
        else:
            raw_input('InvitePreScreenPage: Wrong button')
示例#15
0
class BusinessDetailsPage(Page):
    url_tail = 'add-business/detail'
    dynamic = False

    def load(self):
        try:
            self.nav = NavigationFunctions(self.driver)
            self.load_body()
            self.menu = menu.SideMenu(self.driver)
            self.header = header.PrivateHeader(self.driver)
            return True
        except (NoSuchElementException, StaleElementReferenceException) as e:
            return False

    def load_body(self):
        self.form = self.driver.find_element_by_class_name('form-horizontal')
        find_by = self.form.find_elements_by_tag_name
        find_by_id = self.form.find_element_by_id
        self.ein_input = find_by('input')[0]
        self.hr_email_input = find_by('input')[1]
        self.business_name_input = find_by('input')[2]
        self.dba_input = find_by('input')[3]

        self.line1_input = find_by_id('recipient_line1')
        self.line2_input = find_by_id('recipient_line2')
        self.city_input = find_by_id('recipient_city')

        # not sure which el we need to click
        self.state_cont = self.form.find_element_by_class_name(
            'state_dropdown')
        self.state_dd = self.state_cont.find_elements_by_tag_name('div')[3]
        self.postal_code_input = find_by_id('recipient_code')
        self.phone_input = find_by('input')[9]
        self.website_input = find_by('input')[10]
        self.continue_button = self.form.find_element_by_class_name(
            'primaryButton')

        self.load_agree_checkbox()

    def load_agree_checkbox(self):
        # cont = self.form.find_element_by_id('agreed')
        # self.agree_checkbox = cont.find_element_by_tag_name('input')
        self.agree_checkbox = self.form.find_element_by_id('agreed')

    # def toggle_agree(self):
    # 	self.scroll_to_bottom()
    # 	self.agree_checkbox.click()
    # 	time.sleep(.4)
    # 	self.load_body()

    def toggle_agree(self):
        # agree_checkbox is touchy.
        # Think you need to reload form after clicking checkbox or submitting form
        # (only need to reload form after submission if you toggle checkbox afterwards)
        self.nav.dismiss_keyboard()
        self.scroll_to_bottom()
        selected = self.agreed()
        if main.get_browser() == 'safari':
            self.nav.click_el(self.agree_cont)
        else:
            self.nav.click_el(self.agree_checkbox)
        if selected is self.agreed():
            print('checkbox not altered!')
        time.sleep(.4)

    def agreed(self):
        try:
            return self.agree_checkbox.is_selected()
        except (StaleElementReferenceException, WebDriverException) as e:
            self.load()
            return self.agree_checkbox.is_selected()

    def get_el(self, name):
        """Return input element given name. None if invalid name"""
        if name == 'business_name':
            return self.business_name_input
        elif name == 'dba':
            return self.dba_input
        elif name == 'ein':
            return self.ein_input
        elif name == 'hr_email':
            return self.hr_email_input
        elif name == 'line1':
            return self.line1_input
        elif name == 'line2':
            return self.line2_input
        elif name == 'city':
            return self.city_input
        elif name == 'postal_code':
            return self.postal_code_input
        elif name == 'phone':
            return self.phone_input
        elif name == 'website':
            return self.website_input
        elif name == 'state':
            if main.is_ios():  # click doesn't regester on self.state_cont
                return self.state_dd
            return self.state_cont
        else:
            return None

    def get(self, name):
        """Return the text of the element with the given name"""
        el = self.get_el(name)
        if el is not None:
            if name == 'state':
                # ignore text in label
                if not main.is_ios():  # ios: el is already the child
                    el = el.find_elements_by_tag_name('div')[0]
                return el.text
            return el.get_attribute('value')
        return None

    def set(self, name, value):
        """Pass in name of el and desired value. Don't use for setting state"""
        el = self.get_el(name)
        if el is not None:
            if name == 'state':
                time.sleep(.4)
                self.nav.dismiss_keyboard()
                self.nav.move_to_el(el)
                self.set_state(value)
            else:
                self.nav.set_input(el, value)

                # ios: Inputs dont seem to update unless you click after setting value
                # i.e. 'Required' errors won't show up just for sending keys.
                # if main.is_ios():
                # 	self.nav.click_el(el)

    def set_state(self, state_text):
        WDW(self.driver, 10).until(
            EC.presence_of_element_located(
                (By.CLASS_NAME, 'sm-state-menuitem')))
        try:
            self.states = self.driver.find_elements_by_class_name(
                'sm-state-menuitem')
            for i, state in enumerate(self.states):
                text = self.states[i].text
                if text == state_text:
                    self.nav.click_el(self.states[i])
                    break
        except NoSuchElementException:
            # couldn't find state. De-select dropdown
            AC(self.driver).send_keys(Keys.ESC).perform()
        WDW(self.driver, 10).until_not(
            EC.presence_of_element_located(
                (By.CLASS_NAME, 'sm-state-menuitem')))

    # select state by typing keys, then selecting state by pressing enter
    # Not used, doesn't work. Issues using AC functions. Use nav functions
    def type_state(self, state):
        self.move_to_el(self.state_dd)
        time.sleep(1.4)  # need decent wait before sending keys
        AC(self.driver).send_keys(state).perform()
        time.sleep(.4)
        AC(self.driver).send_keys(Keys.ENTER).perform()
        time.sleep(.4)

    def click_continue(self):
        self.scroll_to_bottom()
        time.sleep(.2)
        self.continue_button.click()

        try:
            WDW(self.driver,
                2).until_not(EC.presence_of_element_located((By.ID, 'agreed')))
            # not on details page anymore
        except TimeoutException:
            # still on page. Need to reload
            self.load()
示例#16
0
class LobbyPage(Page):
    url_tail = 'settings/employer/'
    dynamic = True

    def load(self):
        #raw_input('loading lobby page')
        try:
            self.nav = NavigationFunctions(self.driver)
            self.load_body()
            self.menu = menu.SideMenu(self.driver, True)
            self.header = header.PrivateHeader(self.driver)
            return True
        except (NoSuchElementException, StaleElementReferenceException,
                IndexError) as e:
            #print('Exception: ' + str(e))
            pass
        return False

    def load_body(self):
        self.load_invitations_card()
        #print('loaded invite card')
        self.load_pending_elections_card()
        #print("loaded pening card")
        self.load_employees_card()
        #print('loaded emp card')

        self.cards = [
            self.invitations_card, self.pending_elections_card,
            self.employees_card
        ]
        self.learn_more = [
            self.invitations_lm, self.pending_elections_lm, self.employees_lm
        ]

        # Probably not on lobby page if there isn't at least 1 card
        card_exists = False
        for card in self.cards:
            if card is not None:
                card_exists = True
        if not card_exists:
            raise NoSuchElementException('No cards found on Lobby page')

    def load_invitations_card(self):
        find_by = self.driver.find_elements_by_class_name
        try:
            self.invitations_card = find_by('card')[0]
            self.invitations_lm = find_by('invitations_card')[0]
        except (NoSuchElementException, IndexError) as e:
            self.invitations_card = None
            self.invitations_lm = None

    def load_pending_elections_card(self):
        find_by = self.driver.find_elements_by_class_name
        try:
            self.pending_elections_card = find_by('card')[1]
            self.pending_elections_lm = find_by('payelections_card')[0]
        except (NoSuchElementException, IndexError) as e:
            self.pending_elections_card = None
            self.pending_elections_lm = None

    def load_employees_card(self):
        find_by = self.driver.find_elements_by_class_name
        try:
            self.employees_card = find_by('card')[2]
            self.employees_lm = find_by('employees_card')[0]
        except (NoSuchElementException, IndexError) as e:
            self.employees_card = None
            self.employees_lm = None

    def click_link(self, link_type='card', index=0):
        """link_type: 'card', or 'learn_more'.  Index: 0, 1, 2"""

        # card or learn more link?
        if link_type.lower() == 'card':
            l = self.cards
        else:
            l = self.learn_more

        try:
            el = l[int(index)]
        except IndexError:
            raise Exception('Invalid card index')

        # make sure element is in view
        if not main.is_desktop():
            el_bottom = self.get_el_location(el, 'bottom')
            window_height = self.get_window_height()
            scroll_distance = el_bottom - window_height
            self.move('down', scroll_distance)

        # make sure menu is closed on desktop
        if not main.is_desktop():
            self.menu.close()
        self.nav.click_el(el)
示例#17
0
class ForEmployersPage(Page):
    url_tail = 'enroll-business'  # Now home page. '' will work
    dynamic = False

    def load(self):
        try:
            WDW(self.driver, 10).until(
                EC.element_to_be_clickable((By.CLASS_NAME, 'form-control')))
            self.nav = NavigationFunctions(self.driver)
            self.load_body()
            self.header = header.PubHeader(self.driver)
            self.footer = footer.PubFooter(self.driver)
            return True
        except (NoSuchElementException, StaleElementReferenceException) as e:
            return False

    def load_body(self):
        find_by = self.driver.find_element_by_class_name
        self.learn_more_button = find_by('learnMoreButton')
        self.load_employer_enroll_form()  # form towards top of page
        self.load_demo_request_form()  # form towards bottom of page
        self.load_page_buttons()

    def load_employer_enroll_form(self):
        self.employer_enroll_form = (
            self.driver.find_element_by_class_name('emp_enroll'))

        find_by = self.employer_enroll_form.find_element_by_tag_name
        self.employer_enroll_input = find_by('input')
        self.employer_enroll_button = find_by('button')

    def load_demo_request_form(self):
        self.demo_request_form = (
            self.driver.find_element_by_class_name('enrollCont'))

        find_by = self.demo_request_form.find_element_by_tag_name
        self.demo_request_input = find_by('input')
        self.demo_request_button = find_by('button')

    def load_page_buttons(self):
        """3 buttons that redirect to employers page, 2 go to about page"""
        find_by = self.driver.find_elements_by_class_name
        # redirects to homepage
        self.employee_button = find_by('employerButton')[0]
        # scrolls up to 1st contact form
        self.enroll_now_button = find_by('employerButton')[1]
        # redirects to about page
        self.about_our_mission_button = find_by('employerButton')[2]

    def click_page_button(self, buttton_num):
        """given num (1,2,3) move to and select appropriate button"""
        el = None
        if button_num == 1:
            el = self.employee_button
        elif button_num == 2:
            el = self.enroll_now_button
        elif button_num == 3:
            el = self.about_our_mission_button

        if el is not None:
            self.nav.click_el(el)
            # AC(self.driver).move_to_element(el).perform()
            # el.click()

    def set_employer_email(self, email):
        self.nav.set_input(self.employer_enroll_input, email)
        # AC(self.driver).move_to_element(self.employer_enroll_input).perform()
        # self.employer_enroll_input.clear()
        # self.employer_enroll_input.send_keys(email)

    def get_employer_email(self):
        return self.employer_enroll_input.get_attribute('value')

    def click_employer_enroll_continue(self):
        self.nav.click_el(self.employer_enroll_button)
        # AC(self.driver).move_to_element(self.employer_enroll_button).perform()
        # self.employer_enroll_button.click()

        # Wait until no longer on page
        try:
            WDW(self.driver, 5).until(
                EC.invisibility_of_element_located(
                    (By.CLASS_NAME, 'form-control')))
        except TimeoutException:
            print(
                "Expected to go to enroll-business/code, still on for employers page"
            )

    def enter_employer_email(self, email):
        self.set_employer_email(email)
        self.click_employer_enroll_continue()

    def set_demo_request_email(self, email):
        self.nav.set_input(self.demo_request_input, email)
        # AC(self.driver).move_to_element(self.demo_request_input).perform()
        # self.demo_request_input.clear()
        # self.demo_request_input.send_keys(email)

    def get_demo_request_email(self):
        return self.demo_request_input.get_attribute('value')

    def click_demo_request_continue(self):
        self.nav.click_el(self.demo_request_button)
        # AC(self.driver).move_to_element(self.demo_request_button).perform()
        # self.demo_request_button.click()

    def enter_demo_request_email(self, email):
        self.set_demo_request_email(email)
        self.click_demo_request_continue()

    def clear_demo_request_popup(self):
        try:
            el = self.driver.find_element_by_class_name('logout_cancel')
            el.click()
            #time.sleep(.4)
            #WDW(self.driver, 10).until(EC.element_to_be_clickable((By.ID, 'demo_email')))
            return True
        except NoSuchElementException:
            return False
示例#18
0
 def __init__(self, driver):
     self.driver = driver
     self.nav = NavigationFunctions(self.driver)
     self.load()
示例#19
0
class Disclosure(Component):
    def __init__(self, driver):
        self.driver = driver
        self.nav = NavigationFunctions(self.driver)
        self.load()

    def load(self):
        self.container = self.driver.find_element_by_class_name('sendForm')
        # see code snippets for results
        # num_divs = len(self.form.find_elements_by_tag_name('div'))
        # for i in xrange(num_divs):
        #     text = self.form.find_elements_by_tag_name('div')[i].text

        self.name = self.read_name()
        self.load_table()

        self.exchange_rate = self.try_load_exchange_rate()
        self.total_to_recipient = self.try_load_total_to_recipient()
        self.load_disclosure_statements()
        self.continue_button = self.container.find_element_by_id(
            'send_conf_button')

    def read_name(self):
        # Ignore stuff before name (Send payroll from Dunkin' Donuts to Jose Ortega)
        text = self.container.find_elements_by_tag_name('div')[2].text
        index = text.find(' to ') + 4
        return text[index - len(text):]

    def load_table(self):
        """Table containing transfer amount, fees, and total"""
        self.table_rows = self.container.find_elements_by_tag_name('tr')
        # returns amount only (in USD)
        self.transfer_amount = self.nav.get_text(
            self.table_rows[0].find_elements_by_tag_name('td')[0])
        # Transfer fee row contains "+ " and " 1.00" (desktop chrome)
        self.transfer_fee = (
            self.table_rows[1].find_elements_by_tag_name('td')[0].text[2:])
        self.transfer_total = self.nav.get_text(
            self.table_rows[2].find_elements_by_tag_name('td')[0])

    def try_load_exchange_rate(self):
        """Amount in MXN. Only exists when sending to MX"""
        try:
            return self.container.find_element_by_id('exchangeRateDiv')
        except NoSuchElementException:
            return None

    def try_load_total_to_recipient(self):
        """Amount in MXN, only exists when sending to MX"""
        try:
            return self.container.find_element_by_id('totalRecipDiv')
        except NoSuchElementException:
            return None

    def load_disclosure_statements(self):
        """Up to 3 disclosure statements"""
        self.disclosure_30 = self.try_load_d_30()
        self.disclosure_less = self.try_load_d_less()
        self.disclosure_notify = self.try_load_d_notify()

    def try_load_d_30(self):
        """You have 30 minutes to cancel this transfer..."""
        try:
            return self.container.find_element_by_id('disclose30MinDiv')
        except NoSuchElementException:
            return None

    def try_load_d_less(self):
        """Recipient may receive less due to fees charged by..."""
        try:
            return self.container.find_element_by_id('discloseLessDiv')
        except NoSuchElementException:
            return None

    def try_load_d_notify(self):
        """You'll be notified when the transfer is complete."""
        try:
            return self.container.find_element_by_id('discloseNotifyDiv')
        except NoSuchElementException:
            return None

    def has_d_30(self):
        return self.disclosure_30 is not None

    def has_d_less(self):
        return self.disclosure_less is not None

    def has_d_notify(self):
        return self.disclosure_notify is not None

    def get_exchange_rate(self):
        if self.exchange_rate is not None:
            return self.exchange_rate.text
        return None

    def get_name(self):
        return self.name

    def get_transfer_amount(self):
        return self.transfer_amount.replace(',', '')

    def get_transfer_fee(self):
        return self.transfer_fee.strip()

    def get_transfer_total(self):
        return self.transfer_total.replace(',', '')

    def get_total_to_recipient(self):
        return self.total_to_recipient.text

    def num_disclosures(self):
        return len(self.statements)

    def click_continue(self):
        self.nav.click_el(self.continue_button)

    def has_error(self):
        try:
            self.error = self.driver.find_element_by_class_name('alert-danger')
            self.error_button = self.error.find_element_by_tag_name('button')
            return True
        except NoSuchElementException:
            self.error = None
            self.error_button = None
        return False

    def has_upper_limit_error(self):
        if self.has_error():
            try:
                error_p = self.error.find_element_by_tag_name('div')
                # raw_input(self.nav.get_text(error_p))
                if 'exceed your deposit limit of USD $999 per day' in self.nav.get_text(
                        error_p):
                    return True
            except NoSuchElementException:
                pass
        return False

    def try_clear_error(self):
        if self.has_error():
            # error not visible on mobile
            if not main.is_desktop():
                self.scroll_to_bottom()
            self.nav.click_el(self.error_button)
            time.sleep(.6)
示例#20
0
class TransferDetailsPage(Page):
    url_tail = '/sent'  #i.e. 'transfer/15717205387'
    dynamic = True

    def load(self, hasPin=False):
        try:
            self.menu = menu.SideMenu(self.driver)
            self.header = header.PrivateHeader(self.driver)
            self.nav = NavigationFunctions(self.driver)
            self.load_body(hasPin)
            return True
        except (NoSuchElementException, StaleElementReferenceException) as e:
            return False

    def load_body(self, hasPin):
        # w/in 30 minute window only
        self.send_now_button = self.try_load_send_now()
        self.cancel_button = self.try_load_cancel()
        self.pin = self.try_load_pin(hasPin)

        # always
        self.continue_button = self.driver.find_element_by_id(
            'transfer_ok_button')
        self.icon_type = self.read_transaction_icon()
        self.recipient_link = self.driver.find_element_by_id('recipientLink')

        self.noRecip_dialog = self.try_load_no_recip_dialog()
        self.delay_disclosure = self.try_load_delay_disclosure()

    def try_load_pin(self, hasPin):
        if hasPin:
            # Force pin to load. Fail loading if it's not there
            return self.driver.find_element_by_class_name('bbva_pin')
        else:
            try:
                return self.driver.find_element_by_class_name('bbva_pin')
            except NoSuchElementException:
                return None

    def try_load_send_now(self):
        try:
            return self.driver.find_element_by_id('send_now_button')
        except NoSuchElementException:
            return None

    def try_load_cancel(self):
        try:
            return self.driver.find_element_by_id('cancel_transfer_button')
        except NoSuchElementException:
            return None

    def try_load_delay_disclosure(self):
        # Appears when MX transfers get delayed by STP
        # Test server: All non-STP clabes get delayed (never sent)
        try:
            container = self.driver.find_element_by_class_name('alert-gray')
            cancel_button = container.find_element_by_tag_name('a')
            return {'container': container, 'cancel_button': cancel_button}
        except NoSuchElementException:
            return None

    def try_load_refund_dialog(self):
        try:
            container = self.driver.find_element_by_class_name('sendmiDlg')
            buttons = container.find_elements_by_tag_name('button')
            if buttons and len(buttons) == 2:
                return {
                    'container': container,
                    'noButton': buttons[0],  # Do not refund, close popup
                    'refundButton': buttons[1],  # Cancel and Refund transfer
                }
            else:
                print('TD: loaded cancel dialog cont, but no/wrong# buttons')
                return None
        except NoSuchElementException:
            return None

    def read_transaction_icon(self):
        """Interpret length of img src to determine image"""
        img = self.driver.find_elements_by_tag_name('img')[0]
        return self.interpret_image(len(img.get_attribute('src')))

    def interpret_image(self, img_src_length):
        """Given length of img_src, determine which icon is used"""
        if img_src_length == 1302:
            return 'clock'
        elif img_src_length == 1314:
            return 'check'
        elif img_src_length == 1274:
            return 'x'
        else:
            return None

    def get_pin(self):
        if self.pin:
            return self.pin.text

    def click_continue(self):
        self.nav.click_el(self.continue_button)

    def send_now(self, action='send'):
        if self.send_now_button is not None:
            self.nav.click_el(self.send_now_button)
            time.sleep(.4)
            return self.send_now_dialog(action)

    def send_now_dialog(self, action):
        # True: 'send now' was successful. Should be back on acct page
        # False: unsuccessful or took more than 20 seconds
        try:
            dialog = self.driver.find_element_by_class_name('sendmiDlg')
            if action is not None:
                buttons = dialog.find_elements_by_tag_name('button')
                if action == 'send':
                    self.nav.click_el(buttons[1])
                    WDW(self.driver, 20).until_not(
                        EC.presence_of_element_located(
                            (By.ID, 'send_now_button')))
                elif action == 'cancel':
                    self.nav.click_el(buttons[0])
                # will spin until we hear back from bankaool (~8 seconds)
                # Goes back to acct page when done.
                # Look for element for 20 seconds or until page changes
                '''timeout = time.time() + 25
        while time.time() < timeout:
          try:
            text = self.send_now_button.text
            # sometimes get stale exception
            # sometimes get webdriverException 'unknown server-side error'
          except (WebDriverException, StaleElementReferenceException) as e:
            # probably successful and not on td page anymore
            return True
          if time.time() > timeout:
            # took too long.
            return False
          else:
            time.sleep(.5)'''

                #Clicked cancel or not on td page anymore
                return True
        except NoSuchElementException:
            pass
        # had issues loading/navigating dialog or performing desired action
        return False

    def refund_transaction(self, action='refund'):
        if self.delay_disclosure:
            self.nav.click_el(self.delay_disclosure['cancel_button'])
            refund_dialog = self.try_load_refund_dialog()
            if refund_dialog:
                if action == 'refund':  # Cancel and refund transfer
                    self.nav.click_el(refund_dialog['refundButton'])
                    time.sleep(3)  # Wait for refund to go through
                else:  # Do nothing, Close dialog
                    self.nav.click_el(refund_dialog['noButton'])

    def cancel_transaction(self, action='cancel transfer'):
        if self.cancel_button is not None:
            self.nav.click_el(self.cancel_button)
            time.sleep(.4)
            self.cancel_dialog(action)

    def cancel_dialog(self, action):
        try:
            dialog = self.driver.find_element_by_class_name('sendmiDlg')
            if action is not None:
                buttons = dialog.find_elements_by_tag_name('button')
                if action == 'cancel transfer':
                    self.nav.click_el(buttons[1])
                    WDW(self.driver, 10).until(
                        EC.presence_of_element_located(
                            (By.ID, 'send_money_button')))
                elif action == 'cancel':
                    self.nav.click_el(buttons[0])
        except NoSuchElementException:
            pass

    def has_noRecip_dialog(self):
        try:
            el = self.driver.find_element_by_id('noRecipDialog')
            return True
        except NoSuchElementException:
            return False

    def try_load_no_recip_dialog(self):
        if self.has_noRecip_dialog():
            res = {}
            res['cont'] = self.find_element('id', 'noRecipDialog')
            res['button'] = self.find_element('id', 'confirmOkButton',
                                              res['cont'])

            return res
        else:
            return None

    def click_recip_link(self):
        self.nav.click_el(self.recipient_link)

    def find_element(self, find_by, identifier, cont='driver', single=True):
        res = None
        if find_by and identifier:
            action = None
            if find_by == 'id':
                if single:
                    if cont == 'driver':
                        action = self.driver.find_element_by_id
                    else:
                        action = cont.find_element_by_id
                else:
                    if cont == 'driver':
                        action = self.driver.find_elements_by_id
                    else:
                        action = cont.find_elements_by_id
            elif find_by == 'class':
                if single:
                    if cont == 'driver':
                        action = self.driver.find_element_by_class_name
                    else:
                        action = cont.find_element_by_class_name
                else:
                    if cont == 'driver':
                        action = self.driver.find_elements_by_class_name
                    else:
                        action = cont.find_elements_by_class_name

            if action:
                try:
                    res = action(identifier)
                except NoSuchElementException:
                    pass
        return res
示例#21
0
class AddBusinessPage(Page):
    url_tail = 'add-business'
    dynamic = False

    def load(self):
        try:
            # Make sure on map page
            WDW(self.driver, 10).until(lambda x: EC.element_to_be_clickable(
                (By.ID, 'busName')) and self.try_click('busName'))
            self.nav = NavigationFunctions(self.driver)
            self.load_body()
            self.menu = menu.SideMenu(self.driver)
            self.header = header.PrivateHeader(self.driver)
            return True
        except (NoSuchElementException, StaleElementReferenceException) as e:
            return False

    def load_body(self):
        by_class = self.driver.find_element_by_class_name
        self.location_input = self.driver.find_element_by_id('busName')
        self.cant_find_button = by_class('sm-skip-button')

    def add(self, location, option=0, expectedFailure=False):
        if self.select_location(location, option):
            timer = 10
            if expectedFailure:  # Don't want to wait full 10 seconds when adding non-US business
                timer = 2
            try:
                WDW(self.driver, timer).until(
                    EC.presence_of_element_located((By.ID, 'agreed')))
                return True
            except Exception as e:
                print('failed to add business')
                return False

    def select_location(self, location, option=0):
        self.type_location(location)
        self.try_hide_keyboard()

        unsetOption = True
        count = 0
        while count < 5:
            try:
                if self.options is not None:
                    self.nav.click_el(self.options[option])
                    # self.options[option].click()
                    try:
                        WDW(self.driver, 5).until(
                            EC.element_to_be_clickable(
                                (By.CLASS_NAME, 'sm-continue-button')))
                        self.click_continue()
                        return True
                    except TimeoutException:
                        # no continue button (i.e. adding non-us business)
                        pass
                return False
            except StaleElementReferenceException:
                # Page might have reloaded
                print('Failed to click location option.')
            count += 1

        return False

    def type_location(self, location):
        self.location_input.clear()
        self.location_input.send_keys(location)
        if main.is_ios():
            self.location_input.click()
        # Wait a couple seconds. Sometimes options change as you type
        time.sleep(2)
        # wait up to 5 seconds for options to show up
        presence = EC.presence_of_all_elements_located
        try:
            self.options = WDW(self.driver, 10).until(
                presence((By.CLASS_NAME, 'sm-place-menuitem')))
        except TimeoutException:
            self.options = None

    def num_results(self):
        self.options = (
            self.driver.find_elements_by_class_name("sm-place-menuitem"))
        return len(self.options)

    def click_continue(self):
        try:
            # need to grab <button> for ios web
            find_by = self.driver.find_element_by_class_name
            self.continue_button = find_by('sm-continue-button')
            self.continue_button.click()
            WDW(self.driver, 10).until_not(
                EC.presence_of_element_located(
                    (By.CLASS_NAME, 'sm-continue-button')))
        except (NoSuchElementException, ElementNotVisibleException,
                WebDriverException) as e:
            pass

    def click_cant_find(self):
        self.cant_find_button.click()
        time.sleep(.2)

    def click_skip(self):
        self.skip_button.click()

    def has_error(self):  # page has non-US business error message
        try:
            error_div = self.driver.find_element_by_class_name('alert-danger')
            text = 'sendmi is only available to businesses in the United States.'
            return text == error_div.text
        except NoSuchElementException:
            return False
示例#22
0
class SignInForm(Component):
    def __init__(self, driver):
        self.driver = driver
        self.nav = NavigationFunctions(self.driver)

    def load(self):
        WDW(self.driver,
            10).until(EC.presence_of_element_located(
                (By.ID, 'signin_form_id')))
        self.form = self.driver.find_element_by_id('signin_form_id')
        self.email_input = self.form.find_element_by_id('signin_form_user')
        self.password_input = self.form.find_element_by_id('signin_form_pw')
        self.show_password_button = self.form.find_element_by_id(
            'show_password')
        self.forgot_password_button = self.form.find_element_by_id(
            'forgot_password')  # (link to reset password)
        self.continue_button = self.form.find_element_by_id('submit_si_button')
        # self.nav.print_source()
        # raw_input('source?')
        return True

    def submit(self, email, password, submit):
        if email or email == '':
            self.set_email(email)
        if password or password == '':
            self.set_password(password)
        if submit:
            self.nav.click_el(self.continue_button)

    def set_email(self, email):
        self.nav.set_input(self.email_input, email)

    def set_password(self, password):
        self.nav.set_input(self.password_input, password)

    def toggle_password(self):
        self.nav.click_el(self.show_password_button)

    def forgot_password(self):
        self.nav.dismiss_keyboard(
        )  # Android web needs to close keyboard. Native not tested.
        self.nav.click_el(self.forgot_password_button)
示例#23
0
class SendForm(Component):
    def __init__(self, driver):
        self.driver = driver
        self.nav = NavigationFunctions(self.driver)
        self.load()

    def load(self):
        self.form = self.driver.find_element_by_class_name('sendForm')
        self.type = self.load_destination_type()

        if self.type == 'atm':
            self.try_load_bbva_picker()
        else:
            self.usd_div = self.form.find_element_by_id('sourceAmountInput')
            self.usd_amount = (
                self.form.find_element_by_id('sourceAmountInput_number'))
            self.usd_input = self.form.find_element_by_id(
                'sourceAmountInput_hide')
            self.mxn_div = self.try_load_mxn_div()
            self.mxn_amount = self.try_load_mxn_amount()
            self.mxn_input = self.try_load_mxn_input()
            # BBVA doesn't have a speed option for MX accounts
            # self.try_load_delivery_speed()

        self.account_balance = (
            self.form.find_element_by_id('accountBalanceDiv'))
        self.exchange_rate = self.try_load_exchange_rate()

        # self.destination = self.form.find_element_by_tag_name('a')
        self.continue_button = self.form.find_element_by_id('send_cont_button')

    def load_destination_type(self):
        # Destination types...
        # 'atm': has currency picker
        # 'bank': has id=sourceAmountInput
        # 'cashout': not implemented yet
        try:
            bbvaAmount = self.form.find_element_by_class_name(
                'picker-item-selected')
            return 'atm'
        except NoSuchElementException:
            return 'bank'

    def try_load_bbva_picker(self):
        try:
            if main.is_desktop():
                self.pickerUp = self.form.find_element_by_id('currencyUp')
                self.pickerDown = self.form.find_element_by_id('currencyDown')
            else:
                self.pickerUp = None
                self.pickerDown = None
            self.pickerOptions = self.form.find_elements_by_class_name(
                'picker-item')
            self.bbvaAmount = (self.form.find_element_by_class_name(
                'picker-item-selected').text.replace(",", ""))
            self.bbvaUSDAmount = (
                self.form.find_element_by_class_name('usd_amount').text)
        except NoSuchElementException:
            self.pickerUp = None
            self.pickerDown = None
            self.pickerOptions = None
            self.bbvaAmount = None
            self.bbvaUSDAmount = None
            print('failed to load bbva picker')

    def try_load_mxn_div(self):
        # only there when sending to MX. Element you click on
        try:
            return self.form.find_element_by_id('destAmountInput')
        except NoSuchElementException:
            return None

    def try_load_mxn_amount(self):
        # only there when sending to MX. Element that has amount as text
        try:
            return self.form.find_element_by_id(
                'destAmountInput_number')  #_number
        except NoSuchElementException:
            return None

    def try_load_mxn_input(self):
        # hidden input element. Send keys to this el on desktop
        try:
            return self.form.find_element_by_id('destAmountInput_hide')
        except NoSuchElementException:
            return None

    def try_load_exchange_rate(self):
        # only there when sending to MX
        try:
            self.exchange_cont = (
                self.form.find_element_by_id('exchangeRateDiv'))
            return self.exchange_cont.find_element_by_tag_name('span')
        except NoSuchElementException:
            return None

    def try_load_delivery_speed(self):
        """Look for delivery speed stuff if sending to MX"""
        if self.mxn_div is not None:
            if 'SORIANA' not in self.destination.text:
                if self.toggle_or_radio() == 'radio':
                    cont = self.form.find_element_by_id('radio_speed')
                    inputs = cont.find_elements_by_tag_name('input')
                    self.radio_fast = inputs[0]
                    self.radio_instant = inputs[1]
                    # self.radio_fast = (
                    #   self.form.find_element_by_id('fastRadioButton'))
                    # self.radio_instant = (
                    #   self.form.find_element_by_id('instantRadioButton'))
                else:
                    self.toggle = self.form.find_element_by_id('instantToggle')
            else:
                self.toggle = None

####################### BBVA functions ########################

    def get_picker_item(self, mxnAmount):
        # Return picker-item that corresponds to desired mxnAmount
        # amount must be multiple of 100
        for i, option in enumerate(self.pickerOptions):
            text = option.text.replace(",", "")
            # print(text)
            if text == mxnAmount:
                return self.pickerOptions[i]
        return None

    def get_picker_index(self):
        # return index of currently selected item
        for i, option in enumerate(self.pickerOptions):
            classes = option.get_attribute('class')
            if 'picker-item-selected' in classes:
                return i
        return None

    def get_direction(self, desired_amount):
        # is current bbva amount clickable? If not, which direction does picker need to move?
        current_amount = self.form.find_element_by_class_name(
            'picker-item-selected').text
        current_amount = current_amount.replace(
            ",", "")  # Strip out commas for Decimal functions

        difference = Decimal(desired_amount) - Decimal(current_amount)
        if (difference >= -200) and (difference <= 200):
            # Desired amount is w/in 200 of current amount. Desired amount should be clickable
            return 'click'
        elif difference > 200:
            # Element not visible. Scroll down
            return 'down'
        else:
            return 'up'

    def move_picker(self, direction):
        if main.is_desktop():
            if direction == 'down':
                self.nav.click_el(self.pickerDown)
            else:
                self.nav.click_el(self.pickerUp)
        else:
            if direction == 'down':
                self.nav.click_el(self.pickerOptions[self.get_picker_index() +
                                                     2])
            else:
                self.nav.click_el(self.pickerOptions[self.get_picker_index() -
                                                     2])

    def set_bbva_amount(self, mxnAmount):
        # move up or down until amount is clickable
        # amount must be in multiples of 100
        if self.type == 'atm' and mxnAmount != self.bbvaAmount:
            # env_type = main.get_env()

            while mxnAmount != self.bbvaAmount:
                direction = self.get_direction(mxnAmount)
                if direction == 'click':
                    item = self.get_picker_item(mxnAmount)
                    self.nav.click_el(item)
                else:
                    self.move_picker(direction)
                time.sleep(.4)

                clsName = 'picker-item-selected'
                self.bbvaAmount = (
                    self.form.find_element_by_class_name(clsName).text.replace(
                        ",", ""))
                self.bbvaUSDAmount = (
                    self.form.find_element_by_class_name('usd_amount').text)

    def get_bbva_amount(self):
        if self.type == 'atm':
            return self.bbvaAmount

    def toggle_or_radio(self):
        """Is UI set to radio buttons or toggle switch?"""
        try:
            el = self.form.find_element_by_id('instantToggle')
            return 'toggle'
        except NoSuchElementException:
            return 'radio'

    def set_speed(self, speed='fast'):
        """Set toggle/radio to given speed"""
        if self.toggle_or_radio() == 'radio':
            self.set_speed_radio(speed)
        else:  # toggle
            self.set_speed_toggle(speed)

    def get_speed(self, speed='toggle'):
        """Return speed indicated by radio/toggle"""
        if self.toggle_or_radio() == 'radio':
            return self.get_speed_radio()
        else:  # default (toggle)
            return self.get_speed_toggle()

    def set_speed_radio(self, speed):
        # has issues clicking 'invisible' elements on Safari desktop
        if speed == 'instant':
            self.click_el(self.radio_instant)
        else:  # default (fast)
            self.click_el(self.radio_fast)

    def get_speed_radio(self):
        """Which radio button is selected? Instant or Fast (default)?"""
        if self.radio_instant.get_attribute('checked'):
            return 'instant'
        else:
            return 'fast'

    def set_speed_toggle(self, speed):
        if self.get_speed_toggle() != speed:
            if main.is_ios():
                el = self.toggle.find_element_by_tag_name('input')
                self.nav.click_el(el)
            else:
                self.move_to_el(self.toggle)

    def get_speed_toggle(self):
        el = self.toggle.find_element_by_tag_name('input')
        if el.get_attribute('checked'):
            return 'instant'
        else:  # default (fast)
            return 'fast'

    def get_balance(self):
        return self.account_balance.text

    def get_exchange_rate(self):
        if self.exchange_rate is not None:
            return self.exchange_rate.text
        return None

    def clear_currency_input(self, currency_type):
        """Clear out amount of given currency_type"""
        # set focus on input
        el = None
        amount = ''
        if currency_type.lower() == 'usd':
            el = self.usd_amount
            amount = self.get_usd()
        elif currency_type.lower() == 'mxn':
            el = self.mxn_amount
            amount = self.get_mxn()

        if el:
            self.nav.click_el(el)

        # Desktop: hit backspace enough times to clear out current amount
        # Mobile: hit backspace (on custom keyboard) enough times to clear
        if main.is_desktop():
            for i in xrange(len(amount)):
                AC(self.driver).send_keys(Keys.BACKSPACE).perform()
        else:  # Mobile: hit backspace on custom keyboard
            self.clear_currency(amount)

    def set_usd(self, amount):
        # clear current amount and enter given amount
        self.clear_currency_input('usd')
        if main.is_desktop():
            self.usd_input.send_keys(str(amount))
            # self.usd_div.send_keys(amount)
        else:
            self.enter_currency(amount)

    def set_mxn(self, amount):
        # clear current amount and enter given amount
        self.clear_currency_input('mxn')
        if main.is_desktop():
            self.mxn_input.send_keys(str(amount))
            # self.mxn_div.send_keys(amount)
        else:
            self.enter_currency(amount)

    def get_usd(self):
        if self.type == 'atm':
            return self.bbvaUSDAmount
        else:
            amount = (self.usd_amount.text).replace(',', '')
            return amount

    def get_mxn(self):
        return self.mxn_amount.text

    def has_error(self):
        try:
            self.error = self.form.find_element_by_class_name('alert-danger')
            self.error_button = self.error.find_element_by_tag_name('button')
            return True
        except NoSuchElementException:
            self.error = None
            self.error_button = None
        return False

    def has_balance_error(self):
        """Return if page has 'You have no money to send.' msg"""
        # This text is difficult to parse (react crap and weird ascii chars).
        # Seems to change sometimes. Last updated 11/29
        if self.has_error():
            try:
                error_p = self.error.find_element_by_tag_name('div')
                if self.nav.get_text(error_p) == 'You have no money to send.':
                    return True
            except NoSuchElementException:
                pass
        return False

    def has_upper_limit_error(self):
        if self.has_error():
            try:
                error_p = self.error.find_element_by_tag_name('div')
                raw_input(self.nav.get_text(error_p))
                if 'exceed your deposit limit of USD $999 per day' in self.nav.get_text(
                        error_p):
                    return True
            except NoSuchElementException:
                pass
        return False

    def try_clear_error(self):
        if self.has_error():
            # error not visible on mobile
            if not main.is_desktop():
                self.scroll_to_bottom()
            self.nav.click_el(self.error_button)
            time.sleep(.6)

    def click_account(self):
        self.nav.click_el(self.destination)
        time.sleep(1)

    def get_account_info(self):
        # get div w/ text els. return bank name and clabe text
        acct_div = self.destination.find_elements_by_tag_name('div')[1]
        account_info = {
            'bank': acct_div.find_elements_by_tag_name('div')[0].text,
            'clabe': acct_div.find_elements_by_tag_name('div')[1].text
        }
        return account_info

    ################## Custom Currency Keyboard ##########################

    def enter_currency(self, amount):
        """Enter given amount using custom keyboard then close keyboard
			Mobile ONLY
			Requires input is focused and custom keyboard is open"""
        try:
            self.keyboard = (
                self.driver.find_element_by_class_name('custom_keyboard'))

            for i in xrange(len(amount)):
                # raw_input('typing index:' + str(i) + ' char:' + str(amount[i]))
                self.click_custom_key(amount[i])

            self.close_custom_keyboard()
            return True  # pass in el w/ amount and return it matches amount?
        except NoSuchElementException:
            return False

    def clear_currency(self, amount):
        """Given amount (as text), press backspace enough to clear.
			Input needs to be selected and custom keyboard open"""
        if amount != '':
            for i in xrange(len(amount)):
                self.click_custom_key('backspace')

    def close_custom_keyboard(self):
        """If open, close custom keyboard"""
        try:
            el = self.driver.find_element_by_id('accountBalanceDiv')
            self.nav.click_el(el)
        except NoSuchElementException:
            print('SendForm: Could not find acct balance to close keyboard')

    def click_custom_key(self, character):
        """Given valid character, press correct key on custom keyboard"""
        key_el = self.get_custom_key(character)
        if key_el is not None:
            self.nav.click_el(key_el)

    def get_custom_key(self, character):
        """return custom keyboard element corresponding to given character"""
        keys = {
            '0': 'key_0',
            '1': 'key_1',
            '2': 'key_2',
            '3': 'key_3',
            '4': 'key_4',
            '5': 'key_5',
            '6': 'key_6',
            '7': 'key_7',
            '8': 'key_8',
            '9': 'key_9',
            '.': 'key_dot',
            'backspace': 'key_back'
        }
        try:
            return self.driver.find_element_by_class_name(keys[character])
        except NoSuchElementException:
            print('could not find key w/ class ' + keys[character])
            return None

    def is_form_enabled(self):
        return self.continue_button.is_enabled()

    def click_continue(self):
        self.continue_button = self.form.find_element_by_id('send_cont_button')
        try:
            WDW(self.driver, 10).until(
                EC.element_to_be_clickable((By.ID, 'send_cont_button')))
        except TimeoutException:
            raise TimeoutException("Send page: Continue button not enabled.")
        self.nav.click_el(self.continue_button)
        try:
            WDW(self.driver, 10).until(
                EC.presence_of_element_located((By.ID, 'send_conf_button')))
        except TimeoutException:
            raise TimeoutException(
                "Send Page: Could not find element on next page.")
class BusinessPrefilledPage(Page):
	url_tail = 'add-business/prefilled'
	dynamic = False

	def load(self):
		try:
			self.nav = NavigationFunctions(self.driver)
			self.load_body()
			self.menu = menu.SideMenu(self.driver)
			self.header = header.PrivateHeader(self.driver)
			return True
		except (NoSuchElementException, StaleElementReferenceException) as e:
			return False

	def load_body(self):
		self.form = self.driver.find_element_by_class_name('form-horizontal')
		find_by = self.form.find_elements_by_tag_name
		self.ein_input = self.form.find_element_by_id('ein')
		self.hr_email_input = self.form.find_element_by_id('hr_email')
		self.details_button = find_by('button')[0]
		self.load_agree_checkbox()

		self.continue_button = self.form.find_element_by_class_name('primaryButton')
		self.load_details() # for when you add address and details auto opens

	def load_agree_checkbox(self):
		if main.is_desktop() and main.get_browser() == 'safari':
			# Safari doesn't like clicking the input element
			labels = self.driver.find_elements_by_tag_name('label')
			self.agree_checkbox = labels[-1]
		else:
			self.agree_checkbox = self.form.find_element_by_id('agreed')

	def click_details(self):
		if main.is_android(): # may need to close keyboard
			self.try_hide_keyboard()
		self.scroll_to_top()
		self.details_button.click()
		self.load_details()
		time.sleep(1)

	def load_details(self):
		try:
			find_by = self.form.find_element_by_id
			self.business_name_input = find_by('title')
			self.dba_input = find_by('dba')
			self.line1_input = find_by('recipient_line1')
			self.line2_input = find_by('recipient_line2')
			self.city_input = find_by('recipient_city')

			# Container div
			self.state_cont = self.form.find_element_by_class_name('state_dropdown')
			# Div w/ value as text
			self.state_dd = self.state_cont.find_elements_by_tag_name('div')[3]

			self.postal_code_input = find_by('recipient_code')
			self.phone_input = find_by('phone')
			self.website_input = find_by('website')
			return True
		except (NoSuchElementException, IndexError) as e:
			return False
		time.sleep(1)

	def get_el(self, name):
		"""Return input element given name. None if invalid name"""
		if name == 'business_name':
			return self.business_name_input
		elif name == 'dba':
			return self.dba_input
		elif name == 'ein':
			return self.ein_input
		elif name == 'hr_email':
			return self.hr_email_input
		elif name == 'line1':
			return self.line1_input
		elif name == 'line2':
			return self.line2_input
		elif name == 'city':
			return self.city_input
		elif name == 'postal_code':
			return self.postal_code_input
		elif name == 'phone':
			return self.phone_input
		elif name == 'website':
			return self.website_input
		elif name == 'state':
			return self.state_dd
		else:
			return None

	def get(self, name):
		count = 0
		done = False
		while not done and count < 5:
			try:
				el = self.get_el(name)
				if el is not None:
					if name == 'state':
						return el.text
					return el.get_attribute('value')
				return None
			except StaleElementReferenceException:
				count += 1

		if count == 5:
			print('Failed to find value: ' + str(name))

	def set(self, name, value):
		"""Given name of el, set desired value"""
		# don't use for setting state. Use type_state() or set_state()
		el = self.get_el(name)
		self.nav.set_input(el, value)
		return True
		# hasNewValue = False
		# if el is not None:
		# 	AC(self.driver).move_to_element(el).perform()
		# 	if name == 'state':
		# 		time.sleep(.4)
		# 		self.set_state(value)
		# 		hasNewValue = True
		# 	else:
		# 		# Sometimes has issues setting value (component redraws?).
		# 		# Loop until it actually sets it
		# 		el.clear()

		# 		timeout = time.time() + 5
		# 		while hasNewValue is False:
		# 			el.send_keys(value)
		# 			if self.get(name) == value:
		# 				hasNewValue = True
		# 			elif time.time() > timeout:
		# 				break
		# 			else:
		# 				time.sleep(.5)
		# return hasNewValue

	def set_state(self, state):
		#raw_input(self.state_dd.text)
		self.move_to_el(self.state_dd)
		WDW(self.driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'sm-state-menuitem')))
		states = self.driver.find_elements_by_class_name('sm-state-menuitem')
		for i, st in enumerate(states):
			text = states[i].text
			if state in text:
				states[i].click()
				break
		WDW(self.driver, 10).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'sm-state-menuitem')))

	# select state by typing keys, then selecting state by pressing enter
	def type_state(self,state):
		# move to input below state (so add button doesn't cover on mobile)
		AC(self.driver).move_to_element(self.postal_code_input).perform()
		self.state_dd.click()
		time.sleep(2) # need decent wait before sending keys
		AC(self.driver).send_keys(state).perform()
		time.sleep(1)
		AC(self.driver).send_keys(Keys.ENTER).perform()
		time.sleep(1)

	def toggle_agree(self):
		# agree_checkbox is touchy.
		# Think you need to reload form after clicking checkbox or submitting form
		# (only need to reload form after submission if you toggle checkbox afterwards)
		self.nav.dismiss_keyboard()
		self.scroll_to_bottom()
		selected = self.agreed()
		if main.get_browser() == 'safari':
			self.nav.click_el(self.agree_cont)
		else:
			self.nav.click_el(self.agree_checkbox)
		if selected is self.agreed():
			print('checkbox not altered!')
		time.sleep(.4)

	def agreed(self):
		# Is agree checkbox selected or not?
		checkbox = self.agree_checkbox
		if main.is_desktop() and main.get_browser() == 'safari':
			checkbox = self.form.find_element_by_id('agreed')
		try:
			return checkbox.is_selected()
		except (StaleElementReferenceException, WebDriverException) as e:
			# Reload page and check again
			self.load()
			checkbox = self.form.find_element_by_id('agreed')
			return checkbox.is_selected()

	def click_continue(self):
		self.scroll_to_bottom()
		time.sleep(.2)
		self.continue_button.click()

		# Have had issues trying to load lobby page after clicking continue
		# Try to verify not on prefilled page anymore
		try:
			WDW(self.driver, 2).until_not(
				EC.presence_of_element_located((By.ID, 'agreed')))
			return True
		except TimeoutException:
			# still on page. Need to reload
			self.load()
			return False
示例#25
0
class EmployeePage(Page):
    url_tail = 'employees'
    dynamic = False
    debug = False

    #################################### Loading ##################################

    def load(self):
        try:
            WDW(self.driver, 10).until(
                lambda x: EC.presence_of_element_located(
                    (By.CLASS_NAME, 'sm-employee-table')) or EC.
                presence_of_element_located((By.CLASS_NAME, 'employeeDiv')))
            self.nav = NavigationFunctions(self.driver)
            self.load_body()
            if EmployeePage.debug:
                raw_input('1')
            self.header = header.PrivateHeader(self.driver)
            if EmployeePage.debug:
                raw_input('2')
            self.menu = menu.SideMenu(self.driver, True)
            return True
        except (NoSuchElementException, StaleElementReferenceException,
                IndexError) as e:
            return False

    def load_body(self):
        # employees, add button, filter toggle, search input

        # this line might fail if you're actually on account page (IndexError)
        # Other inputs exist if filter options are visible
        self.search_input = self.driver.find_elements_by_tag_name('input')[0]
        find_by = self.driver.find_element_by_class_name
        if EmployeePage.debug:
            raw_input('3')
        self.employees = self.load_employees()
        if EmployeePage.debug:
            raw_input('4')
        self.add_button = self.driver.find_element_by_id('fab_button')
        self.filter_button = (
            self.driver.find_element_by_class_name('filter_toggle'))
        if EmployeePage.debug:
            raw_input('5')
        self.filter_pane = self.driver.find_element_by_class_name(
            'ReactCollapse--collapse')
        if EmployeePage.debug:
            raw_input('6')
        self.try_load_filter_opts()
        if EmployeePage.debug:
            raw_input('7')
        self.try_load_sort_opts()
        if EmployeePage.debug:
            raw_input('8')

    def load_employees(self):
        # Should always be at least 1 entry in table.
        # Fail to load page if cant find any
        if main.is_desktop():  # return table row elements
            find_by = self.driver.find_element_by_class_name
            css = 'sm-employee-table'
            table = find_by(css)
            employees = table.find_elements_by_tag_name('tr')[1:]
        else:  # return employee entry elements
            employees = self.driver.find_elements_by_class_name('employeeDiv')
        if len(employees) == 0:
            raise NoSuchElementException("Couldn't find employees in table.")
        return employees

    def try_load_filter_opts(self):
        """Only visible when filter button is toggled"""
        opts = [None] * 5
        if self.filters_open():
            try:
                # possibly need to grab child of each opt for ios
                opts[0] = self.driver.find_element_by_id('filter_invited')
                opts[1] = self.driver.find_element_by_id('filter_inactive')
                opts[2] = self.driver.find_element_by_id('filter_active')
                opts[3] = self.driver.find_element_by_id('filter_removed')
                opts[4] = self.driver.find_element_by_id('filter_terminated')
            except NoSuchElementException:
                pass
        self.filter_opts = opts

    def try_load_sort_opts(self):
        # desktop: grab <th> els from first table
        # mobile: page inputs (if visible)
        opts = [None] * 5
        if main.is_desktop():
            t = self.driver.find_elements_by_class_name('sm-employee-table')
            opts = t[0].find_elements_by_tag_name('th')
        elif self.filters_open():
            # Mobile: only there when filters are open
            opts[0] = self.driver.find_element_by_id('sort_first_name')
            opts[1] = self.driver.find_element_by_id('sort_employee_id')
            opts[2] = self.driver.find_element_by_id('sort_state')
            opts[3] = self.driver.find_element_by_id('sort_elect_amount')
            opts[4] = self.driver.find_element_by_id('sort_modified')
        self.sort_opts = opts

    def load_participate_dialog(self):
        try:
            buttons = self.driver.find_elements_by_tag_name('button')
            self.participate = buttons[-2]
            self.skip = buttons[-1]
            # IDs not pushed to test server yet.
            # self.participate = self.driver.find_element_by_id("newBus_participate")
            # self.skip = self.driver.find_elements_by_id("newBus_skip")
            return True
        except NoSuchElementException:
            self.participate = None
            self.skip = None
            return False

    def handle_participate_dialog(self, action='skip'):
        self.load_participate_dialog()
        if self.participate is not None:
            if action == 'participate':
                self.participate.click()
            else:
                self.skip.click()
                time.sleep(1)
        else:
            print('No participate dialog found')

########################### Employee/Table functions ##########################

    def num_employees(self):
        return len(self.employees)

    def get_employee(self, find_by, identifier, get_info=True):
        """ find_by: 'index', 'name', 'id'
			identifier: string
			get_info: True=return employee data, False=return employee element
		"""
        emp = None
        if find_by == 'index':
            emp = self.employees[int(identifier)]
        elif find_by == 'name':
            emp = self.get_emp_by_name(identifier)
        elif find_by == 'id':
            emp = self.get_emp_by_id(identifier)

        if emp is None:
            return None
        elif get_info:
            return self.get_emp_data(emp)
        else:
            return emp

    def get_emp_by_name(self, name):
        for employee in self.employees:
            find_by = employee.find_elements_by_tag_name
            if main.is_desktop():
                text = find_by('td')[0].text
            else:
                text = find_by('div')[2].text

            # raw_input(text)
            if text == name:
                #print('found employee: ' + name)
                return employee
        return None

    def get_emp_by_id(self, emp_id):
        for employee in self.employees:
            find_by = employee.find_elements_by_tag_name
            # print(employee.text)
            tds = find_by('td')
            # raw_input('# tds: ' + str(len(tds)))

            if main.is_desktop():
                el = find_by('td')[1]
                text = el.text
            else:
                el = find_by('div')[3]
                text = str(el.text)[13:]

            if text == emp_id:
                return employee
        return None

    def get_emp_data(self, employee):
        """ given employee div, parse text and return employee dict """
        emp = None
        find_by = employee.find_elements_by_tag_name
        if str(type(employee)) != "<type 'NoneType'>" and main.is_desktop():
            # columns = employee.find_elements_by_tag_name("td")
            emp = {
                'name': find_by('td')[0].text,
                'id': find_by('td')[1].text,
                'status': find_by('td')[2].text,
                'election': find_by('td')[3].text,
                'date_changed': find_by('td')[4].text
            }
        elif str(type(employee)) != "<type 'NoneType'>":
            emp = {
                'name': find_by('div')[2].text,
                'id': find_by('div')[3].text[13:],
                'status': find_by('div')[4].text[8:],  #Fail 4:20p, StaleEl
                'election': find_by('div')[5].text[17:],  #Fail 4:15p, StaleEl
                'date_changed': find_by('div')[6].text[14:]
            }

        # raw_input(str(emp))
        return emp

    def employee_menu(self, find_by, identifier, command_text='click'):
        """Find employee, 'click': just open menu, 'reinvite', 'remove' """
        emp = self.get_employee(find_by, identifier, False)
        try:
            emp_menu = emp.find_element_by_tag_name('button')
            # move to emp. click toast (if visible)
            self.nav.click_el(emp_menu)
            # AC(self.driver).move_to_element(emp).perform()
            time.sleep(.2)
            self.click_toast()
            time.sleep(.2)

            # open emp menu, click action matching command_text
            self.move_to_el(emp_menu)
            time.sleep(.4)
            if command_text != 'click':
                class_name = "{command}_employee".format(
                    command=command_text.lower())
                option = self.driver.find_element_by_class_name(class_name)
                option.click()
                WDW(self.driver, 10).until(
                    EC.presence_of_element_located(
                        (By.CLASS_NAME, 'confirm_remove')))
                if command_text.lower() == 'remove':
                    self.load_remove_form()
        except NoSuchElementException:
            print('something went wrong in employee_menu()')

    def load_reinvite_form(self):
        # shouldn't have invites in table anymore
        pass
        # self.reinvite_cancel_button = (
        # 	self.driver.find_element_by_xpath("//span[text() = 'Cancel']")
        # )
        # self.reinvite_ok_button = (
        # 	self.driver.find_element_by_xpath("//span[text() = 'OK']")
        # )

    def cancel_reinvite(self):
        self.reinvite_cancel_button.click()

    def reinvite(self):
        self.reinvite_ok_button.click()
        time.sleep(1)

    def load_remove_form(self):
        self.remove_select_cont = self.driver.find_element_by_id(
            'remove_select')
        self.remove_select = (
            self.remove_select_cont.find_elements_by_tag_name('div')[2])
        self.remove_cancel_button = (
            self.driver.find_element_by_class_name('cancel_remove'))
        self.remove_remove_button = (
            self.driver.find_element_by_class_name('confirm_remove'))

    def select_remove_new_status(self, new_status):
        self.remove_select.click()
        time.sleep(1)
        action = AC(self.driver)
        action.send_keys(new_status)
        action.send_keys(Keys.ENTER)
        action.perform()

    def remove_employee(self, find_by, identifier, remove=True):
        self.employee_menu(find_by, identifier, 'Remove')
        time.sleep(.2)
        self.remove_remove_button.click()

        # Table redraws after removing someone. Wait for first employee to go stale
        try:
            WDW(self.driver, 10).until(EC.staleness_of(self.employees[0]))
        except (WebDriverException, NoSuchElementException,
                StaleElementReferenceException) as e:
            # employee element probably already gone
            pass

        # Wait for table to redraw
        if main.is_desktop():
            WDW(self.driver, 10).until(
                EC.presence_of_element_located(
                    (By.CLASS_NAME, 'sm-employee-table')))
        else:
            WDW(self.driver, 10).until(
                EC.presence_of_element_located((By.CLASS_NAME, 'employeeDiv')))

        # Should be good to go. Load page
        self.load()

    def click_employee(self, find_by, identifier):
        emp = self.get_employee(find_by, identifier, False)
        if emp is None:
            print('no employee found')
            return False
        else:
            if main.is_ios():  # ios needs to click a child div (not menu div)
                emp = emp.find_elements_by_tag_name('div')[3]
            #elif main.is_desktop():
            #	emp = emp.find_elements_by_tag_name('td')[1]
            self.click_toast()
            # move_to_el handles navigating to employee and clicking
            self.move_to_el(emp)  # emp.click()
            time.sleep(.4)
            return True

############################ Add Employee Functions ###########################

    def click_plus(self):
        self.add_button.click()
        time.sleep(.4)
        try:
            find_by = self.driver.find_element_by_id
            self.add_employee_button = find_by('add_employee')
            # only has multiple employees option on desktop
            if main.is_desktop():
                self.add_multiple_employees = find_by('add_employees')
        except NoSuchElementException:
            fail = 1 + '2'
            # problem if these elements don't exist

    def click_add_employee(self):
        self.add_employee_button.click()

    def click_add_multiple_employees(self):
        self.add_multiple_employees.click()

################################## Filter Functions ###########################

    def filters_open(self):
        # are filter options visible on page?

        return self.filter_pane.size['height'] != 0
        # Filters always drawn on page, tucked in zero-height el when not shown.
        # BUG: May return True, where should be False, if filter options pane is closing, but not closed.

    def filter_is_active(self, index):
        # self.filter_opts[index].find_element_by_xpath("parent::*")
        prop = 'background-color'
        color = 'rgba(56, 217, 244, 1)'
        el = self.filter_opts[index].find_elements_by_tag_name('div')[0]
        # raw_input('bg: ' + el.value_of_css_property(prop))
        return el.value_of_css_property(prop) == color

    def toggle_filter(self):
        """Click element to hide/show filter options"""
        #print('toggling filter')
        self.filter_button.click()
        #WDW(self.driver, 10).until(EC.presence_of_element_located((By.ID, 'filter_terminated')))
        time.sleep(1)
        # update filter/sort options
        self.try_load_filter_opts()
        if not main.is_desktop():
            self.try_load_sort_opts()
        #raw_input('what happening?')
        time.sleep(1)

    def set_filter(self, pattern):
        """toggle individual filter (int), or apply pattern (list)"""

        # make sure filter options visible
        if not self.filters_open():
            self.toggle_filter()

        if type(pattern) is int:
            self.filter_opts[pattern].click()
        elif type(pattern) is list:
            current_filter = self.get_filters()
            for i in xrange(len(pattern)):
                if (pattern[i] != current_filter[i]):
                    self.filter_opts[i].click()
                    time.sleep(.4)

        time.sleep(1)  #Can't get a WDW condition to load correctly.
        WDW(self.driver, 20).until(lambda x: EC.visibility_of_element_located(
            (By.TAG_NAME, 'tr')) or EC.visibility_of_all_elements_located(
                (By.CLASS_NAME, 'employeeDiv')))
        self.load()

    def get_filters(self):
        filters = [None] * 5
        for i, filt in enumerate(self.filter_opts):
            if self.filter_is_active(i):
                filters[i] = 1
            else:
                filters[i] = 0
        return filters

################################ Sort Functions ###############################

    def get_active_sort(self):
        if main.is_desktop():
            return self.get_active_desktop_sort()
        else:
            return self.get_active_web_sort()

    def get_active_desktop_sort(self):
        """return index in self.sort_opts that is currently active"""
        # non-active options have opacity of 0.2
        for i in xrange(5):
            # raw_input(str(i))
            arrow_el = (self.sort_opts[i].find_element_by_tag_name("svg"))
            opacity = arrow_el.value_of_css_property("opacity")
            if opacity != "0.2":
                return i
        return None

    def get_active_web_sort(self):
        """Return index in self.sort_opts that is currently active"""
        # ensure sort options are visible
        if not main.is_desktop() and not self.filters_open():
            #if main.is_desktop() is not True and self.filters_open() is False:
            self.toggle_filter()

        # return index of sort opt that has active color
        for i, opt in enumerate(self.sort_opts):
            prop = 'background-color'
            color = 'rgba(56, 217, 244, 1)'
            if opt.value_of_css_property(prop) == color:
                return i

    def get_sort_direction(self):
        """Determine index of current sort setting.
			return True if sort is normal, False if reverse"""
        direction = True
        if main.is_desktop():
            active_index = self.get_active_desktop_sort()
            arrow_el = (
                self.sort_opts[active_index].find_element_by_tag_name("path"))
            path = arrow_el.get_attribute('d')
            if path == "M7 14l5-5 5 5z":  # vs "M7 10l5 5 5-5z" for normal
                direction = False
        else:
            direction = self.get_mobile_sort_direction()
        return direction

    def get_mobile_sort_direction(self):
        """Return opposite of reverse order checkbox selected status"""
        if not self.filters_open():
            self.toggle_filter()

        # should be 2 inputs. Search, reverse checkbox
        reverse_order_checkbox = (
            self.driver.find_elements_by_tag_name('input')[1])
        return not reverse_order_checkbox.is_selected()

    def get_sort(self):
        column = self.get_active_sort()
        direction = self.get_sort_direction()
        return [column, direction]

    def click_sort(self, index):
        self.sort_opts[index].click()
        time.sleep(.2)

    def get_first_emp(self):
        self.load()
        return self.get_employee('index', 0)

    def set_sort(self, index, direction=True):
        # open sort options if not visible (always vis on desktop)
        # Index: 0=name, 1=ID, 2=Status, 3=election 4=date changed
        if not main.is_desktop() and not self.filters_open():
            self.toggle_filter()

        cur_sort = self.get_sort()
        old_first_emp = self.get_first_emp()
        #first_emp = self.get_employee('index', 0)

        if cur_sort[0] != int(index) or cur_sort[1] != direction:
            if cur_sort[0] != int(index):
                self.click_sort(index)
                cur_sort = self.get_sort()

            if cur_sort[1] != direction:
                self.reverse_sort(cur_sort[0])

        #raw_input('waiting on...?')
        #giving time for page to update. WDW until old_first_el != first_el and first_el is not None?
            time.sleep(2)
            '''WDW(self.driver, 10).until(lambda x:
				EC.presence_of_element_located((By.TAG_NAME , 'tr')) or
				EC.visibility_of_element_located((By.CLASS_NAME ,'employeeDiv'))
				)'''
            #	lambda x : old_first_emp != self.get_first_emp() and self.get_first_emp() is not None
            #	)
        self.load()

    def reverse_sort(self, index):
        """Desktop: Toggle current sort. Web: Click sort toggle button"""
        if main.is_desktop():
            self.click_sort(index)
        else:
            self.click_sort_toggle()

    def click_sort_toggle(self):
        reverse_order_checkbox = (
            self.driver.find_elements_by_tag_name('input')[1])
        reverse_order_checkbox.click()

############################### Toast Functions ###############################

    def get_secret_urls(self):
        WDW(self.driver,
            10).until(EC.presence_of_element_located((By.ID, 'testSnackId')))
        self.load()
        elem = self.driver.find_elements_by_class_name("sm-secret-code")
        try:
            email_string = elem[0].text
            try:
                email_url = email_string[0:email_string.index(' => ')]
            except ValueError:
                pass
            email = email_string[email_string.index('email:') + 6:]
        except NoSuchElementException:
            email = None
            email_url = None
        try:
            phone_string = elem[1].text
            phone = phone_string[phone_string.index('phone:') + 6:]
            phone_url = phone_string[0:phone_string.index(' => ')]
        except IndexError:
            phone = None
            phone_url = None
        return {
            'email': email,
            'phone': phone,
            'email_url': email_url,
            'phone_url': phone_url
        }

    def click_toast(self):
        if self.has_toast():
            self.toast.click()
            time.sleep(.4)

    def has_toast(self):
        # is toast visible on page?
        try:
            self.toast = self.driver.find_element_by_id('testSnackId')
            return True
        except NoSuchElementException:
            return False
示例#26
0
class PubHeader(Component):
    """load content of element id='sendmi_public_appbar'"""
    def __init__(self, driver):
        self.driver = driver
        self.nav = NavigationFunctions(self.driver)
        self.load()

    def load(self):
        self.cont = self.load_cont()

        find_by = self.cont.find_element_by_id

        # Todo: Load Logo, language dd

        # ID nightmare...
        # self.logo = find_by('public_logo_sm')
        self.logo = find_by('public_logo')
        # self.language_dd = find_by('locale_dropdown')

        self.pre_signed_in = self.load_pre_sign_in()
        # desktop only
        if main.is_desktop():
            # signin dropdown only on desktop when not signed in
            # never on signin or signin/code
            # Contents of dropdown do not exist when dropdown is closed
            try:
                self.sign_in_button = (
                    self.cont.find_element_by_id('signin_dropdown'))
            except NoSuchElementException:
                self.sign_in_button = None

        # forgot pw form loads when 'forgot' link clicked
        self.for_employers = self.load_employers_link()
        self.for_employees = self.load_employees_link()

        # mobile web only
        self.hamburger = self.try_load_hamburger()

    def load_cont(self):
        # IDs are a nightmare
        # look for sendmi_public_appbar or sendmi_appbar
        try:
            cont = self.driver.find_element_by_id('sendmi_appbar')
            return cont
        except NoSuchElementException:
            try:
                cont = self.driver.find_element_by_id('sendmi_public_appbar')
                return cont
            except NoSuchElementException:
                print('Failed to load appbar container')
                raise NoSuchElementException('Failed to load appbar container')

    def load_pre_sign_in(self):
        # Desktop: item in header
        # Mobile: option in header action menu
        try:
            return self.cont.find_element_by_id("signin_myaccount")
        except NoSuchElementException:
            return None

    def load_employers_link(self):
        """Desktop only. Pages: homepage, contact us, about"""
        # Note: Is same id for option in action menu
        try:
            return self.cont.find_element_by_id('public_enroll_employers')
        except NoSuchElementException:
            return None

    def load_employees_link(self):
        """Desktop only. Pages: enroll, contact us, about"""
        # Note: Is same id for option in action menu
        try:
            return self.cont.find_element_by_id('public_enroll_employees')
        except NoSuchElementException:
            return None

    def try_load_hamburger(self):
        # Only on mobile. Menu contents only visible when open
        try:
            return self.driver.find_element_by_id('nav_toggle')
        except NoSuchElementException:
            return None

    # header functions

    def click_logo(self):
        """click visible header logo"""
        logo = self.logo
        if main.is_desktop() and not self.logo.is_displayed():
            # scrolled to top on desktop and we need to load other logo
            logo = self.cont.find_element_by_id('public_logo')

        self.nav.click_el(logo)

    def click_for_employers(self):
        if self.for_employers != None:
            self.for_employers.click()
            WDW(self.driver,
                10).until(EC.presence_of_element_located(
                    (By.ID, 'demo_email')))

    def click_for_employees(self):
        if main.is_desktop():
            if self.for_employees != None:
                self.for_employees.click()
                WDW(self.driver, 10).until(
                    EC.presence_of_element_located((By.ID, 'contactEmail2')))
        else:
            self.select_action('employees')

    def select_action(self, text):
        # text: 'emp' (employers or employees), 'sign in', or 'signed in'
        if self.hamburger != None:
            if not self.action_menu_open():
                self.nav.click_el(self.hamburger)
                WDW(self.driver,
                    10).until(lambda x: EC.element_to_be_clickable((
                        By.ID, 'public_enroll')) or EC.element_to_be_clickable(
                            (By.ID, 'signin_myaccount')))
                time.sleep(.4)

            elId = None
            if text.lower() == 'employers':
                elId = 'public_enroll_employers'
            elif text.lower() == 'employees':
                elId = 'public_enroll_employees'
            elif text.lower() == 'sign in':
                elId = 'public_enroll'
            elif text.lower() == 'signed in':
                elId = 'signin_myaccount'

            if elId:
                try:
                    el = self.driver.find_element_by_id(elId)
                except NoSuchElementException:
                    print('unable to find element w/ id: ' + str(elId))

            if el:
                self.nav.click_el(el)
                return True
        return False

    def action_menu_open(self):
        # Does action menu exist (web only) and is it open?
        find_by = self.driver.find_element_by_class_name
        if (self.hamburger != None):
            try:
                el = find_by('MuiDrawer-paperAnchorTop-069')
                return el.is_displayed()
            except NoSuchElementException:
                pass
        return False

    def sign_in_submit(self, email='', password='', submit=True):
        # No sign in dropdown on mobile
        if main.is_desktop():
            # Make sure dropdown is visible (won't have dropdown on signin page)
            if self.sign_in_button:
                if not self.sign_in_open():
                    self.nav.click_el(self.sign_in_button)

                self.signInForm = SignInForm(self.driver)
                WDW(self.driver, 10).until(lambda x: self.signInForm.load())
                self.signInForm.submit(email, password, submit)

    def forgot_password_submit(self, email='', submit=True):
        # No forgor password dropdown on mobile
        if main.is_desktop():
            # Neither dropdowns are visible
            if not self.forgot_password_open() and not self.sign_in_open():
                self.nav.click_el(self.sign_in_button)
                self.signInForm = SignInForm(self.driver)

            # Sign In form is visible
            if self.sign_in_open():
                WDW(self.driver, 10).until(lambda x: self.signInForm.load())
                self.signInForm.forgot_password()

            # Should be on forgotPWForm
            self.forgotPWForm = ForgotPasswordForm(self.driver)
            WDW(self.driver, 10).until(lambda x: self.forgotPWForm.load())
            self.forgotPWForm.submit(email, submit)

    def sign_in_open(self):
        # is signin dropdown open?
        if main.is_desktop() and self.sign_in_button:
            try:
                el = self.driver.find_element_by_id('forgot_password')
                if el.is_displayed():
                    return True
            except NoSuchElementException:
                pass
        return False

    def forgot_password_open(self):
        # Is forgot password form visible?
        if main.is_desktop() and self.sign_in_button:
            try:
                resetPWform = self.driver.find_element_by_class_name(
                    'resetPWForm')
                if resetPWform.is_displayed():
                    return True
            except NoSuchElementException:
                pass
        return False

    def signed_in(self):
        # is user signed in?
        # Used to tell which item we should expect in header/action dd
        return self.pre_signed_in is not None

    def sign_in(self):
        if self.signed_in():
            if main.is_desktop():
                self.move_to_el(self.pre_signed_in)
            else:
                self.select_action('signed in')
示例#27
0
class BusinessSettingsPage(Page):
    url_tail = 'business-settings'
    dynamic = False

    def load(self):
        try:
            self.nav = NavigationFunctions(self.driver)
            self.load_body()
            self.header = header.PrivateHeader(self.driver)
            self.menu = menu.SideMenu(self.driver)
            if main.is_web() and main.is_ios():
                self.clear_ios_footer()
            return True
        except (NoSuchElementException, StaleElementReferenceException) as e:
            return False

    def load_body(self):
        self.form = self.driver.find_element_by_tag_name('form')
        self.load_business_name()
        self.load_dba()
        self.load_ein()
        self.load_hr()
        self.load_phone()
        self.load_website()

        self.load_address()
        self.remove_button = (
            self.driver.find_element_by_class_name('removeButton'))

    def load_business_name(self):
        cont = self.driver.find_element_by_id('busName_cont')
        # Android native: grab parent of input
        # else: grab input
        # if main.is_android() and not main.is_web():
        # 	self.business_name_input = cont.find_elements_by_tag_name('div')[1]
        # else:
        self.business_name_input = cont.find_element_by_tag_name('input')

    def load_dba(self):
        cont = self.driver.find_element_by_id('dba_cont')
        # if main.is_android() and not main.is_web():
        # 	self.dba_input = cont.find_elements_by_tag_name('div')[1]
        # else:
        self.dba_input = cont.find_element_by_tag_name('input')

    def load_ein(self):
        cont = self.driver.find_element_by_id('ein_cont')
        # if main.is_android() and not main.is_web():
        # 	self.ein_input = cont.find_elements_by_tag_name('div')[1]
        # else:
        self.ein_input = cont.find_element_by_tag_name('input')

    def load_hr(self):
        cont = self.driver.find_element_by_id('hr_cont')
        # if main.is_android() and not main.is_web():
        # 	self.hr_email_input = cont.find_elements_by_tag_name('div')[1]
        # else:
        self.hr_email_input = cont.find_element_by_tag_name('input')

    def load_phone(self):
        cont = self.driver.find_element_by_id('phone_cont')
        # if main.is_android() and not main.is_web():
        # 	self.phone_input = cont.find_elements_by_tag_name('div')[1]
        # else:
        self.phone_input = cont.find_element_by_tag_name('input')

    def load_website(self):
        cont = self.driver.find_element_by_id('website_cont')
        # if main.is_android() and not main.is_web():
        # 	self.website_input = cont.find_elements_by_tag_name('div')[1]
        # else:
        self.website_input = cont.find_element_by_tag_name('input')

    def load_address(self):
        find_by_id = self.form.find_element_by_id
        # line1, line2, city, state, zip
        self.line1_input = find_by_id('recipient_line1')
        self.line2_input = find_by_id('recipient_line2')
        self.city_input = find_by_id('recipient_city')
        self.state_cont = self.form.find_element_by_class_name(
            'state_dropdown')
        self.state_dd = self.state_cont.find_elements_by_tag_name('div')[3]
        self.postal_code_input = find_by_id('recipient_code')

        # cont = self.driver.find_element_by_id('zip_cont')
        # if main.is_android() and not main.is_web():
        # 	self.postal_code_input = cont.find_elements_by_tag_name('div')[1]
        # else:
        # 	self.postal_code_input = cont.find_element_by_tag_name('input')

    def clear_ios_footer(self):
        # scroll down a little bit to lose ios browser footer. Scroll back to top
        self.ios_scroll('down', 100)
        self.scroll_to_top()
        time.sleep(1)

    def set_state(self, state):
        if self.state_dd.tag_name != 'input':
            self.nav.click_el(self.state_dd)
            time.sleep(1)
            ActionChains(self.driver).send_keys(state).perform()
            ActionChains(self.driver).send_keys(Keys.ENTER).perform()
            time.sleep(1)
        else:
            self.state_dd.clear()
            self.state_dd.send_keys(state)

    # select state by typing keys, then selecting state by pressing enter
    def type_state(self, state):
        ActionChains(self.driver).move_to_element(self.state_dd).perform()
        self.nav.click_el(self.state_dd)
        time.sleep(1.4)  # wait before sending keys
        ActionChains(self.driver).send_keys(state).perform()
        time.sleep(.4)
        ActionChains(self.driver).send_keys(Keys.ENTER).perform()

    def set(self, name, value):
        """Set text of input element with given name"""
        # don't use for setting state. Use type_state() or set_state()
        el = self.get_el(name)
        # AC(self.driver).move_to_element(el).perform()
        # time.sleep(.6)
        # autosave causes issues if you don't use clear_input() instead of clear()
        # self.clear_input(el)
        self.nav.set_input(el, value)

    def get_el(self, name):
        """Return input element given name. None if invalid name"""
        if name == 'business_name':
            return self.business_name_input
        elif name == 'dba':
            return self.dba_input
        elif name == 'ein':
            return self.ein_input
        elif name == 'hr_email':
            return self.hr_email_input
        elif name == 'line1':
            return self.line1_input
        elif name == 'line2':
            return self.line2_input
        elif name == 'city':
            return self.city_input
        elif name == 'postal_code':
            return self.postal_code_input
        elif name == 'phone':
            return self.phone_input
        elif name == 'website':
            return self.website_input
        elif name == 'state':
            return self.state_cont
        else:
            return None

    def get(self, name):
        """Given name, return the value of element"""
        el = self.get_el(name)
        if el is not None:
            # State: return text (not label text) Else: return input value
            if name == 'state':
                div = el.find_elements_by_tag_name('div')[0]
                return div.text
            return el.get_attribute('value')
        return None

    def remove_business(self, code):
        self.click_remove()
        self.set_remove_code(code)
        self.click_confirm_remove()

    def click_remove(self):
        """Click 'remove' button, then load elements in confirmation popup"""
        self.nav.dismiss_keyboard(
        )  # Hide keyboard first. Otherwise you won't be at bottom of page
        self.scroll_to_bottom()
        self.remove_button = (
            self.driver.find_element_by_class_name('removeButton'))
        self.nav.click_el(self.remove_button, True)
        time.sleep(1)
        self.try_load_remove_popup()

    def try_load_remove_popup(self):
        try:
            self.confirm_code_input = (
                self.driver.find_element_by_id('removeBusCode'))
            buttons = self.driver.find_elements_by_tag_name('button')
            self.cancel_remove_button = (
                self.driver.find_element_by_class_name(
                    'remove_business_cancel'))
            self.confirm_remove_button = (
                self.driver.find_element_by_class_name('remove_business_ok'))
        except NoSuchElementException:
            self.confirm_code_input = None
            self.cancel_remove_button = None
            self.confirm_remove_button = None

    def click_cancel_remove(self):
        self.nav.click_el(self.cancel_remove_button)

    def click_confirm_remove(self):
        if main.is_android():
            self.try_hide_keyboard()
            time.sleep(.4)
        self.move_to_el(self.confirm_remove_button)
        time.sleep(2)

    def set_remove_code(self, code):
        self.confirm_code_input.clear()
        self.confirm_code_input.send_keys(code)
        if main.is_ios():  # send_keys doesn't seem to update react component.
            self.confirm_code_input.send_keys('')

    def confirm_remove_button_enabled(self):
        """Does confirm remove button exist and is it enabled?"""
        if self.confirm_remove_button is None:
            return False
        return self.confirm_remove_button.is_enabled()

    def saved(self):
        """Determines if the form is valid"""
        try:
            WebDriverWait(self.driver, 6).until_not(
                lambda x: x.find_element_by_class_name('uil-ring-css'))
            return True
        except TimeoutException:
            return False
示例#28
0
class DOBPage(Page):
    url_tail = "/i/"
    dynamic = True

    def load(self):
        try:
            self.nav = NavigationFunctions(self.driver)
            self.h1 = self.try_load_expired_header()
            # load continue button if normal, signin button if link is expired
            if self.h1 and self.h1.text == 'Oops!':
                self.load_expired_link()
            else:
                self.header = header.PubHeader(self.driver)
                self.load_body()

            return True
        except (NoSuchElementException, StaleElementReferenceException,
                IndexError) as e:
            return False

    def try_load_expired_header(self):
        # expired link has <h1> element w/ text 'Oops!'
        try:
            return self.driver.find_element_by_tag_name('h1')
        except NoSuchElementException:
            return None

    def load_expired_link(self):
        """Invite has expired. Or error"""
        self.signin_button = self.driver.find_element_by_id('signin_button')

    def load_body(self):
        self.form = self.driver.find_element_by_tag_name('form')
        self.dob_input = self.form.find_element_by_id('dob')
        self.zip_input = self.form.find_element_by_id('zip')
        self.continue_button = (
            self.form.find_element_by_class_name('primaryButton'))

    def set_dob(self, dob):
        self.nav.set_input(self.dob_input, dob)

    def set_zip(self, zipcode):
        self.nav.set_input(self.zip_input, zipcode)

    def get_dob(self):
        return self.dob_input.get_attribute('value')

    def get_zip(self):
        return self.zip_input.get_attribute('value')

    def click_continue(self):
        if self.is_expired():  # (expired link)
            self.nav.move_to_el(self.signin_button)
        else:  # (normal link)
            self.nav.move_to_el(self.continue_button)

    def is_expired(self):
        """Return True if signin_button visible"""
        try:
            return self.signin_button.is_displayed()
        except Exception:
            return False