Пример #1
0
class CategoriesGeneral():
    ADD_CATEGORY_BUTTON = "Add Category Button"
    MERGE_CATEGORIES_BUTTON = "Merge Categories Button"
    CATEGORY_ITEM = "Category Item"
    CATEGORY_INFO = '//android.view.ViewGroup[@content-desc="Category Item"]/android.view.ViewGroup'
    CONFIRM_MERGE_BUTTON = "Merge"

    # TYPE
    EXPENSES = "Expenses"
    INCOME = "Income"

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def set_type(self, type_of_category):
        """ Selects income or expense set of categories
        :param type_of_category: str
        """
        if type_of_category == "random":
            type_of_category = random.choice([self.EXPENSES, self.INCOME])
        elif type_of_category == "expenses":
            type_of_category = self.EXPENSES
        else:
            type_of_category = self.INCOME

        self.ew.wait_and_tap_element(type_of_category, 5)
Пример #2
0
 def __init__(self, driver):
     self.driver = driver
     self.action = TouchAction(self.driver)
     self.categories_general = CategoriesGeneral(self.driver)
     self.category_detail = CategoryDetail(self.driver)
     self.ew = ElementWrapper(self.driver)
     self.rs = Resolutions(self.driver)
Пример #3
0
 def __init__(self, driver):
     self.driver = driver
     self.action = TouchAction(self.driver)
     self.ew = ElementWrapper(self.driver)
     self.period_filter = PeriodFilter(self.driver)
     self.rs = Resolutions(self.driver)
     self.timeline_general = TimelineGeneral(self.driver)
     self.transaction_detail = TransactionDetail(self.driver)
Пример #4
0
 def __init__(self, driver):
     self.driver = driver
     self.action = TouchAction(self.driver)
     self.ew = ElementWrapper(self.driver)
     self.rs = Resolutions(self.driver)
     self.wallets_general = WalletsGeneral(self.driver)
     self.wallet_detail = WalletDetail(self.driver)
     self.wallets_overview = WalletOverview(self.driver)
Пример #5
0
 def __init__(self, driver):
     self.driver = driver
     self.action = TouchAction(self.driver)
     self.budget_detail = BudgetDetail(self.driver)
     self.budgets_general = BudgetsGeneral(self.driver)
     self.budget_overview = BudgetOverview(self.driver)
     self.ew = ElementWrapper(self.driver)
     self.rs = Resolutions(self.driver)
     self.transaction_detail = TransactionDetail(self.driver)
Пример #6
0
 def __init__(self, driver):
     self.driver = driver
     self.ew = ElementWrapper(self.driver)
     self.email_password = EmailPassword(self.driver)
     self.facebook = Facebook(self.driver)
     self.google = Google(self.driver)
     self.marketing_dialog = MarketingDialog(self.driver)
     self.more_general = MoreGeneral(self.driver)
     self.timeline_general = TimelineGeneral(self.driver)
     self.user_profile = UserProfile(self.driver)
     self.welcome_screen = WelcomeScreen(self.driver)
Пример #7
0
class AdvancedGeneral:
    ADVANCED_HEADER = "Advanced Header"
    EXPORT = "Export"

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)
        self.export_general = ExportGeneral(self.driver)

    def go_to_export(self):
        """Opens export screen"""
        self.ew.wait_and_tap_element(self.EXPORT, 10)
        self.ew.wait_till_element_is_visible(self.export_general.EXPORT_HEADER, 10)
Пример #8
0
class MainCurrency:
    CURRENCY_PICKER = "Select currency Picker"
    if PLATFORM == "Android":
        SELECTED_CURRENCY = '//android.view.ViewGroup[@content-desc="Main Currency"]/android.view.ViewGroup/android.widget.TextView[2]'
    else:
        SELECTED_CURRENCY = 'label == "Main Currency"'

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def set_currency(self, currency):
        """ Selecting main currency of user
        :param currency: str
        """

        if currency == "random":
            currency = random.choice(vs.accessible_currencies)

        self.ew.wait_and_tap_element(f"Currency {currency}", 10)
        self.ew.wait_till_element_is_not_visible(self.CURRENCY_PICKER, 10)

    def get_currency(self):
        """ Getting selected main currency
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.SELECTED_CURRENCY, 10)
        if PLATFORM == "Android":
            return self.ew.get_text_of_element(self.SELECTED_CURRENCY)
        else:
            return self.ew.get_attribute(self.SELECTED_CURRENCY, "name")
Пример #9
0
class EmailPassword:
    EMAIL_INPUT = "Email Input"
    PASSWORD_INPUT = "Password Input"
    EXISTING_EMAIL_DIALOG = "Email Already In Use Dialog"
    LOGIN_BUTTON = "Login Button"
    SIGN_UP_BUTTON = "Sign Up Button"
    INVALID_CREDENTIALS_DIALOG = "Invalid Credentials Dialog"
    VALIDATION_ERROR_WARNING = "Validation Error Warning"

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def set_email(self, email):
        """ Inserts email of user into email input
        :param email: str
        """
        self.ew.wait_till_element_is_visible(self.EMAIL_INPUT, 5)
        self.ew.get_element(self.EMAIL_INPUT).send_keys(email)

    def set_password(self, password):
        """ Inserts password of user into password input
        :param password: str
        """
        self.ew.wait_till_element_is_visible(self.PASSWORD_INPUT, 5)
        self.ew.get_element(self.PASSWORD_INPUT).send_keys(password)
Пример #10
0
class BankSearchScreen():
    SEARCH_INPUT = "Search Input"
    if PLATFORM == "Android":
        BANK_ITEM = "Bank Item"
    else:
        BANK_ITEM = 'label == "Bank Item"'

    BACK_BUTTON = "Back Button"

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def search_bank_by_search_box(self, bank):
        """ Searches for a bank via search textbox
        :param bank: str
        """
        if bank == "random":
            bank = "Fake Bank Simple"

        self.ew.get_element(self.SEARCH_INPUT).send_keys(bank)
        if PLATFORM == "Android":
            self.ew.wait_till_element_is_visible(bank, 15)
        else:
            self.ew.wait_till_element_is_visible(
                f'label == "Bank Item" AND name == "{bank}"', 15)
            if self.driver.is_keyboard_shown():
                self.driver.hide_keyboard()
        self.ew.wait_and_tap_element(self.BANK_ITEM, 15)
Пример #11
0
class BankAccountsGeneral():
    CONNECT_BANK_ACCOUNT_BUTTON = "Connect Bank Account Button"
    BACK_BUTTON = "Back Button"

    if PLATFORM == "Android":
        BANK_ITEM = "Bank Item"
        BANK_ITEM_NAME = '//android.view.ViewGroup[@content-desc="Bank Item"]/android.widget.TextView'
    else:
        BANK_ITEM = '**/XCUIElementTypeOther[`label == "Bank Item"`][3]'

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def open_bank_account(self):
        """Opens bank account settings"""
        self.ew.wait_and_tap_element(self.BANK_ITEM, 15)
Пример #12
0
class WalletsGeneral:
    NAVIGATION_WALLETS = "Navigation Wallets"
    WALLETS_ANIMATED_HEADER = "Wallets Animated Header"
    ADD_WALLET_BUTTON = "Add Wallet Button"
    CONNECT_BANK_BUTTON = "Connect Bank Button"
    if PLATFORM == "Android":
        WALLET_ITEM = '//android.widget.ScrollView[@content-desc="Wallets List"]/android.view.ViewGroup/android.view.ViewGroup[1]'
    else:
        WALLET_ITEM = '(//XCUIElementTypeOther[@name="Wallets List"])[2]/XCUIElementTypeScrollView//XCUIElementTypeOther//XCUIElementTypeOther'

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def go_to_wallets(self):
        """Opens Wallets navigation section"""
        self.ew.wait_and_tap_element(self.NAVIGATION_WALLETS, 30)
        self.ew.wait_till_element_is_visible(self.WALLETS_ANIMATED_HEADER, 30)
Пример #13
0
class TransferOriginationModal():
    ORIGINATION_MODAL = "Transfer Origination"
    DESTINATION_MODAL = "Transfer Destination"
    CONFIRM_BUTTON = "Confirm Button"

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)
        self.transaction_detail = TransactionDetail(self.driver)

    def create_as_new_transaction(self):
        """Clicking on button 'Create as new transaction'"""
        self.ew.tap_element(self.CONFIRM_BUTTON)

    def is_origination_modal_present(self):
        """ Check if modal is present
        :return: bool
        """
        self.ew.wait_till_element_is_not_visible(
            self.transaction_detail.SAVE_TRANSACTION_BUTTON, 10)
        if self.ew.is_element_present(self.ORIGINATION_MODAL):
            return True
        else:
            return False
Пример #14
0
class BankAccountDetail():
    CONSENT = "Consent"
    CONSENT_WEBVIEW = "Spendee"
    REMOVE_BUTTON = "Remove Button"
    REMOVE_CONFIRM = "Remove"
    EYE_ICON = "Eye Icon-true"
    BACK_BUTTON = "Back Button"

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def open_consent(self):
        """Opens consent screen"""
        self.ew.wait_and_tap_element(self.CONSENT, 15)
        self.ew.wait_till_element_is_not_visible(self.CONSENT, 10)

    def disconnect_bank_account(self):
        """Removes bank connection"""
        self.ew.wait_and_tap_element(self.REMOVE_BUTTON, 15)
        self.ew.wait_and_tap_element(self.REMOVE_CONFIRM, 5)
        self.ew.wait_till_element_is_not_visible(self.REMOVE_CONFIRM, 10)

    def hide_bank_wallets(self, wallets):
        """ Hides requested number of bank wallets of 1 bank connection
        :param wallets: int
        :return:
        """
        if wallets == "random":
            wallets = random.randint(1, 3)

        x = 0
        all_wallets = self.ew.get_elements(self.EYE_ICON)
        for i in all_wallets:
            x = x + 1
            if x <= wallets:
                i.click()
Пример #15
0
class BudgetValidator:
    def __init__(self, driver):
        self.driver = driver
        self.action = TouchAction(self.driver)
        self.budget_detail = BudgetDetail(self.driver)
        self.budgets_general = BudgetsGeneral(self.driver)
        self.budget_overview = BudgetOverview(self.driver)
        self.ew = ElementWrapper(self.driver)
        self.rs = Resolutions(self.driver)
        self.transaction_detail = TransactionDetail(self.driver)

    def get_all_attributes(self):
        """ Getting all attributes of budget
        :return: dict
        """
        all_attributes = {
            "name": self.budget_detail.get_name(),
            "amount": self.budget_detail.get_amount(),
            "currency": self.budget_detail.get_currency(),
            "wallets": self.budget_detail.get_wallets(),
            "categories": self.budget_detail.get_categories(),
            "recurrence": self.budget_detail.get_recurrence(),
            "start_date": self.transaction_detail.get_date("start"),
            "end_date": self.transaction_detail.get_date("end")
        }

        return all_attributes

    def is_budget_existing(self, attributes):
        """ Checking if budget is visible inside Budgets section
        :param attributes: dict
        :return: bool
        """
        budget_locator = f"{attributes['name']}/" \
                         f"{attributes['amount']}/" \
                         f"{attributes['currency']}/" \
                         f"{self.adjust_wallets(attributes['wallets'])}/" \
                         f"{self.adjust_categories(attributes['categories'])}/" \
                         f"{self.adjust_recurrence(attributes['recurrence'])}/" \
                         f"{attributes['start_date']}/" \
                         f"{self.adjust_end_date(attributes['end_date'], attributes['start_date'], attributes['recurrence'])}"

        print(f'ATTRIBUTES: {attributes}')
        print(f'LOCATOR: {budget_locator}')

        if self.ew.is_element_present(self.budget_overview.OVERVIEW_BUTTON):
            self.ew.tap_element(self.budget_overview.BACK_BUTTON)
            self.ew.wait_till_element_is_visible(
                self.budgets_general.BUDGETS_HEADER, 10)

        android_timeout = time.time() + 30
        ios_timeout = time.time() + 5
        res = self.rs.get_resolution()
        is_budget_present = self.ew.is_element_present(budget_locator)
        while is_budget_present is False:
            if PLATFORM == "Android":
                self.action.long_press(None, self.rs.all_resolutions[f"{res}"]["x"],
                                       self.rs.all_resolutions[f"{res}"]["budget_overview_y_start"]) \
                    .move_to(None, self.rs.all_resolutions[f"{res}"]["x"],
                             self.rs.all_resolutions[f"{res}"]["budget_overview_y_end"]) \
                    .release().perform()
                is_budget_present = self.ew.is_element_present(budget_locator)
                if time.time() > android_timeout:
                    return False
            else:
                is_budget_present = self.ew.is_element_present(budget_locator)
                if time.time() > ios_timeout:
                    return False
        return True

    def adjust_wallets(self, wallets):
        """ Adjusting wallets for budget locator
        :param wallets: str
        :return: str
        """
        if wallets == "All Wallets":
            return "undefined"
        elif wallets in ["0", "2", "3", "4", "5", "6", "7", "8", "9", "10"]:
            return wallets
        else:
            return "1"

    def adjust_categories(self, categories):
        """ Adjusting categories for budget locator
        :param categories: str
        :return: str
        """
        if categories == "All Expenses":
            return "undefined"
        else:
            return categories

    def adjust_recurrence(self, recurrence):
        """ Adjusting recurrence for recurrence locator
        :param recurrence: str
        :return: str
        """
        recurrences_in_app = [
            "once", "day", "week", "every two weeks", "month", "year"
        ]
        return recurrences_in_app[vs.budget_recurrences.index(recurrence)]

    def adjust_end_date(self, end_date, start_date, recurrence):
        """ Adjusting end date for budget locator
        :param end_date: str
        :param start_date: str
        :param recurrence: str
        :return: str
        """
        if end_date is None:
            year_start, month_start, day_start = (
                int(x) for x in start_date.split('-'))
            start_date = datetime.date(year_start, month_start, day_start)

            if (year_start % 4) == 0:
                if (year_start % 100) == 0:
                    if (year_start % 400) == 0:
                        is_year_leap = True
                    else:
                        is_year_leap = False
                else:
                    is_year_leap = True
            else:
                is_year_leap = False

            if recurrence == "Daily":
                end_date = start_date
            elif recurrence == "Weekly":
                end_date = str(start_date + datetime.timedelta(days=6))
            elif recurrence == "Biweekly":
                end_date = str(start_date + datetime.timedelta(days=13))
            elif recurrence == "Monthly":
                if month_start in ["01", "03", "05", "07", "08", "10", "12"]:
                    end_date = str(start_date + datetime.timedelta(days=30))
                elif month_start in ["04", "06", "09", "11"]:
                    end_date = str(start_date + datetime.timedelta(days=29))
                else:
                    if is_year_leap:
                        end_date = str(start_date +
                                       datetime.timedelta(days=28))
                    else:
                        end_date = str(start_date +
                                       datetime.timedelta(days=27))
            elif recurrence == "Yearly":
                if is_year_leap:
                    end_date = str(start_date + datetime.timedelta(days=365))
                else:
                    end_date = str(start_date + datetime.timedelta(days=364))

        return end_date
Пример #16
0
class WalletsActions:
    def __init__(self, driver):
        self.driver = driver
        self.action = TouchAction(self.driver)
        self.ew = ElementWrapper(self.driver)
        self.rs = Resolutions(self.driver)
        self.wallets_general = WalletsGeneral(self.driver)
        self.wallet_detail = WalletDetail(self.driver)
        self.wallets_overview = WalletOverview(self.driver)

    def create_wallet(self, name, amount, currency, categories):
        """ Opens wallet create screen and sets requested attributes
        :param name: str or None
        :param amount: str or None
        :param currency: str or None
        :param categories: str or int or None
        """
        self.wallets_general.go_to_wallets()
        self.open_wallet_create_screen()
        self.wallet_detail.set_name(name)
        if amount is not None:
            self.wallet_detail.set_amount(amount)
        if currency is not None:
            self.wallet_detail.set_currency(currency)
        if categories is not None:
            self.wallet_detail.set_categories(categories)

    def open_wallet_create_screen(self):
        """Opens wallet create screen"""
        self.ew.wait_till_element_is_visible(
            self.wallets_general.WALLETS_ANIMATED_HEADER, 10)

        if PLATFORM == "Android":
            add_button_visible = self.ew.is_element_present(
                self.wallets_general.ADD_WALLET_BUTTON)
            while add_button_visible is False:
                res = self.rs.get_resolution()
                self.action.long_press(None, self.rs.all_resolutions[f"{res}"]["x"],
                                       self.rs.all_resolutions[f"{res}"]["wallets_overview_y_start"]) \
                    .move_to(None, self.rs.all_resolutions[f"{res}"]["x"],
                             self.rs.all_resolutions[f"{res}"]["wallets_overview_y_end"]) \
                    .release().perform()
                add_button_visible = self.ew.is_element_present(
                    self.wallets_general.ADD_WALLET_BUTTON)
        else:
            add_button_visible = self.ew.get_attribute(
                self.wallets_general.ADD_WALLET_BUTTON, "visible")
            while add_button_visible == "false":
                res = self.rs.get_resolution()
                self.driver.execute_script(
                    "mobile: dragFromToForDuration", {
                        "duration":
                        "0.1",
                        "fromX":
                        self.rs.all_resolutions[f"{res}"]["x"],
                        "fromY":
                        self.rs.all_resolutions[f"{res}"]
                        ["wallets_overview_y_start"],
                        "toX":
                        self.rs.all_resolutions[f"{res}"]["x"],
                        "toY":
                        self.rs.all_resolutions[f"{res}"]
                        ["wallets_overview_y_end"]
                    })
                add_button_visible = self.ew.get_attribute(
                    self.wallets_general.ADD_WALLET_BUTTON, "visible")

        self.ew.wait_and_tap_element(self.wallets_general.ADD_WALLET_BUTTON, 5)
        self.ew.wait_till_element_is_visible(self.wallet_detail.WALLET_HEADER,
                                             10)

    def save_wallet(self):
        """Clicks on save wallet button"""
        if self.driver.is_keyboard_shown():
            self.driver.hide_keyboard()
        self.ew.wait_and_tap_element(self.wallet_detail.SAVE_WALLET_BUTTON, 10)
        self.ew.wait_till_element_is_not_visible(
            self.wallet_detail.SAVE_WALLET_BUTTON, 10)

    def open_wallet(self):
        """Opens existing wallet"""
        self.wallets_general.go_to_wallets()
        self.ew.wait_till_element_is_visible(
            self.wallets_general.WALLETS_ANIMATED_HEADER, 10)
        self.ew.wait_and_tap_element(self.wallets_general.WALLET_ITEM, 5)
        self.ew.wait_and_tap_element(self.wallets_overview.EDIT_BUTTON, 5)
        self.ew.wait_till_element_is_visible(self.wallet_detail.WALLET_HEADER,
                                             5)

    def edit_wallet(self, name, amount, currency, categories):
        """Changes requested attributes of wallet
        :param name: str or None
        :param amount: str or None
        :param currency: str or None
        :param categories: str or int or None
        """
        self.open_wallet()
        if name is not None:
            if PLATFORM == "Android":
                self.ew.get_element(self.wallet_detail.NAME_INPUT).clear()
            else:
                self.ew.get_element(
                    self.wallet_detail.SELECTED_NAME_IOS).clear()
            self.wallet_detail.set_name(name)
        if amount is not None:
            self.ew.wait_and_tap_element(self.wallet_detail.AMOUNT_INPUT, 5)
            self.ew.wait_till_element_is_visible(
                self.wallet_detail.NUMPAD_CLEAR, 10)
            for i in range(6):
                self.ew.tap_element(self.wallet_detail.NUMPAD_CLEAR)
            self.ew.tap_element(self.wallet_detail.NUMPAD_BACKDROP)
            self.wallet_detail.set_amount(amount)
        if currency is not None:
            self.wallet_detail.set_currency(currency)
        if categories is not None:
            self.wallet_detail.set_categories(categories)

    def delete_wallet(self):
        """Deletes wallet from wallet detail"""
        self.ew.wait_and_tap_element(self.wallet_detail.TRASH_ICON, 10)
        self.ew.wait_and_tap_element(self.wallet_detail.DELETE_BUTTON, 10)
        self.ew.wait_till_element_is_visible(
            self.wallets_general.WALLETS_ANIMATED_HEADER, 10)

    def invite_user_to_wallet(self):
        """Opens wallet and invitation screen"""
        self.open_wallet()
        self.wallet_detail.invite_user()
Пример #17
0
class BudgetDetail():
    # OTHER
    BUDGET_HEADER = "Budget Header"
    SAVE_BUDGET_BUTTON = "Save Budget Button"
    TRASH_ICON = "Trash Icon"
    DELETE_BUTTON = "Delete"

    if PLATFORM == "Android":
        DISCARD_CHANGES = "android:id/button1"
    else:
        DISCARD_CHANGES = "Discard changes"

    # NAME
    NAME_INPUT = "Name Input"
    SELECTED_NAME_IOS = '**/XCUIElementTypeTextField[`label == "Name Input"`]'

    # AMOUNT
    if PLATFORM == "Android":
        AMOUNT_INPUT = "Amount Input"
    else:
        AMOUNT_INPUT = '**/XCUIElementTypeOther[`label == "Amount Input"`][2]'
    SELECTED_AMOUNT = "Currency Input"

    # KEYBOARD
    KEYBOARD = {"0": "Numpad 0", "1": "Numpad 1", "2": "Numpad 2", "3": "Numpad 3", "4": "Numpad 4", "5": "Numpad 5",
                "6": "Numpad 6", "7": "Numpad 7", "8": "Numpad 8", "9": "Numpad 9",
                ".": "Numpad Decimal Point", ",": "Numpad Decimal Point"}
    NUMPAD_BACKDROP = "Numpad Backdrop"
    NUMPAD_CLEAR = "Numpad Clear"

    # CURRENCY
    CURRENCY = "Currency"
    if PLATFORM == "Android":
        SELECTED_CURRENCY = '//android.view.ViewGroup[@content-desc="Currency"]/android.view.ViewGroup/android.view.ViewGroup/android.widget.EditText'
        CURRENCY_PICKER = "Select currency Picker"
    else:
        SELECTED_CURRENCY = '**/XCUIElementTypeOther[`label == "Currency"`][1]'
        CURRENCY_PICKER = 'label == "Select currency"'

    # WALLETS
    if PLATFORM == "Android":
        WALLET_ITEM = '//android.view.ViewGroup[@content-desc="Select Wallets Picker"]/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup'
        WALLETS = "Wallets"
    else:
        WALLET_ITEM = "Wallet Item"
        WALLETS = 'label == "Wallets"'
    WALLET_PICKER = "Select Wallets Picker"
    SELECTED_WALLETS_ANDROID = '//android.view.ViewGroup[@content-desc="Wallets"]/android.view.ViewGroup/android.widget.TextView[2]'
    SELECTED_WALLETS_ANDROID_2 = '//android.view.ViewGroup[@content-desc="Wallets"]/android.widget.TextView[2]'

    # CATEGORIES
    CATEGORIES = "Categories"
    HEADER_BUDGET_FOR = "Header Budget For"
    SELECT_ALL_CHECKED = "Select All-checked"
    SELECT_ALL_UNCHECKED = "Select All-unchecked"
    SELECT_ALL_PART = "Select All-part"
    if PLATFORM == "Android":
        CATEGORIES = "Categories"
        CATEGORY_ITEM = '//android.view.ViewGroup[@content-desc="Category Item"]/android.view.ViewGroup'
        SELECTED_CATEGORIES_ANDROID = '//android.view.ViewGroup[@content-desc="Categories"]/android.widget.TextView[2]'
        SELECTED_CATEGORIES_ANDROID_2 = '//android.view.ViewGroup[@content-desc="Categories"]/android.view.ViewGroup/android.widget.TextView[2]'
    else:
        CATEGORY_ITEM = 'label == "Category Item"'
        CATEGORIES = 'label == "Categories"'
    BACK_BUTTON = "Back Button"

    # RECURRENCE
    if PLATFORM == "Android":
        RECURRENCE = "Recurrence"
        SELECTED_RECURRENCE_ANDROID = '//android.view.ViewGroup[@content-desc="Recurrence"]/android.widget.TextView[2]'
        SELECTED_RECURRENCE_ANDROID_EDIT = '//android.view.ViewGroup[@content-desc="Recurrence"]/android.view.ViewGroup/android.widget.TextView[2]'
    else:
        RECURRENCE = 'label == "Recurrence"'
    RECURRENCE_PICKER = "Recurrence Picker"

    # START DATE
    if PLATFORM == "Android":
        START_DATE = "Start Date"
    else:
        START_DATE = 'label == "Start Date"'
    CALENDAR_PICKER = "Select date Picker"

    # END DATE
    if PLATFORM == "Android":
        END_DATE = "End Date"
    else:
        END_DATE = 'label == "End Date"'

    def __init__(self, driver):
        self.driver = driver
        self.action = TouchAction(self.driver)
        self.ew = ElementWrapper(self.driver)
        self.rs = Resolutions(self.driver)
        self.transaction_detail = TransactionDetail(self.driver)

    def set_name(self, name):
        """ Insert name into name input
        :param name: str
        """
        if name == "random":
            name = ''.join([random.choice(string.ascii_lowercase + string.digits) for n in range(0, 8)])

        self.ew.wait_till_element_is_visible(self.NAME_INPUT, 5)
        self.ew.get_element(self.NAME_INPUT).send_keys(name)

        vr.validate_input_against_output(name, self.get_name())

    def get_name(self):
        """ Gets name of budget from name input
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.NAME_INPUT, 5)

        if PLATFORM == "Android":
            return self.ew.get_text_of_element(self.NAME_INPUT)
        else:
            return self.ew.get_text_of_element(self.SELECTED_NAME_IOS)

    def set_amount(self, amount):
        """ Insert amount into amount input
        :param amount: str
        """
        if amount == "random":
            amount = str(random.randint(1, 99))

        self.ew.wait_and_tap_element(self.AMOUNT_INPUT, 5)
        self.ew.wait_till_element_is_visible(self.KEYBOARD["1"], 10)
        amount_list = list(amount)
        for i in amount_list:
            self.ew.wait_and_tap_element(self.KEYBOARD[i], 5)
        self.ew.wait_and_tap_element(self.NUMPAD_BACKDROP, 5)

        vr.validate_input_against_output(amount, self.get_amount())

    def get_amount(self):
        """ Gets amount of budget from amount input
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.AMOUNT_INPUT, 5)
        if PLATFORM == "Android":
            return self.ew.get_text_of_element(self.SELECTED_AMOUNT)
        else:
            return self.ew.get_attribute(self.AMOUNT_INPUT, "name")

    def set_currency(self, currency):
        """ Selects currency of budget
        :param currency: str
        """
        if currency == "random":
            currency = random.choice(vs.accessible_currencies)

        self.ew.wait_and_tap_element(self.CURRENCY, 5)
        self.ew.wait_till_element_is_visible(self.CURRENCY_PICKER, 10)
        self.ew.wait_and_tap_element(f"Currency {currency}", 10)
        self.ew.wait_till_element_is_not_visible(self.CURRENCY_PICKER, 10)
        vr.validate_input_against_output(currency, self.get_currency())

    def get_currency(self):
        """ Gets selected currency of budget
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.CURRENCY, 5)
        if PLATFORM == "Android":
            return self.ew.get_text_of_element(self.SELECTED_CURRENCY)
        else:
            return self.ew.get_attribute(self.SELECTED_CURRENCY, "name")

    def set_wallets(self, wallets):
        """ Selects wallets from wallets picker
        :param wallets: str or int
        """

        self.ew.wait_and_tap_element(self.WALLETS, 5)
        self.ew.wait_till_element_is_visible(self.WALLET_PICKER, 5)

        all_visible_wallets = self.count_wallets()[0]
        selected_wallets = self.count_wallets()[1]
        non_selected_wallets = self.count_wallets()[2]
        total_wallets = len(all_visible_wallets)
        total_selected_wallets = len(selected_wallets)
        total_non_selected_wallets = len(non_selected_wallets)

        if wallets == "random":
            wallets_to_select = random.sample(all_visible_wallets, random.randrange(0, len(all_visible_wallets)))
            for i in wallets_to_select:
                if PLATFORM == "Android":
                    self.ew.tap_element(i)
                else:
                    self.ew.tap_element(f'label == "{i}"')
        elif wallets == "all_selected":
            if total_wallets != total_selected_wallets:
                for i in non_selected_wallets:
                    if PLATFORM == "Android":
                        self.ew.tap_element(i)
                    else:
                        self.ew.tap_element(f'label == "{i}"')
        elif wallets == "all_unselected":
            if total_wallets != total_non_selected_wallets:
                for i in selected_wallets:
                    if PLATFORM == "Android":
                        self.ew.tap_element(i)
                    else:
                        self.ew.tap_element(f'label == "{i}"')
        elif isinstance(wallets, int):
            x = 0
            actual_selected_wallets = self.count_wallets()[1]
            for i in all_visible_wallets:
                x = x + 1
                if x <= wallets and len(actual_selected_wallets) > 1:
                    if PLATFORM == "Android":
                        self.ew.tap_element(i)
                    else:
                        self.ew.tap_element(f'label == "{i}"')
                    actual_selected_wallets = self.count_wallets()[1]

        selected_wallets = self.count_wallets()[1]
        total_wallets = len(self.count_wallets()[0])
        total_selected_wallets = len(selected_wallets)

        if total_wallets == total_selected_wallets:
            v_input = "All Wallets"
        elif total_selected_wallets == 1:
            v_input = selected_wallets[0].split('-')[0]
        else:
            v_input = str(total_selected_wallets)

        self.ew.tap_element('Backdrop')
        vr.validate_input_against_output(v_input, self.get_wallets())

    def count_wallets(self):
        """ Gets all visible wallets, currently selected wallets and not_selected wallets from wallets picker
        :return: tuple of lists
        """
        if PLATFORM == "Android":
            all_visible_wallets = self.ew.get_attributes(self.WALLET_ITEM, "content-desc")
        else:
            all_visible_wallets = self.ew.get_attributes(self.WALLET_ITEM, "label")

        selected_wallets = []
        non_selected_wallets = []
        for i in all_visible_wallets:
            if i.endswith('true'):
                selected_wallets.append(i)
            else:
                non_selected_wallets.append(i)
        return (all_visible_wallets, selected_wallets, non_selected_wallets)

    def get_wallets(self):
        """ Gets selected wallets (number, name or 'All Wallets')
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.WALLETS, 5)

        if PLATFORM == "Android":
            result = self.ew.get_text_of_element(self.SELECTED_WALLETS_ANDROID)
            if result is None:
                result = self.ew.get_text_of_element(self.SELECTED_WALLETS_ANDROID_2)
        else:
            result = self.ew.get_attribute(self.WALLETS, "name")
        return result

    def set_categories(self, categories):
        """ Selects requested number of categories
        :param categories: str
        """

        self.ew.wait_and_tap_element(self.CATEGORIES, 5)
        self.ew.wait_till_element_is_visible(self.HEADER_BUDGET_FOR, 5)

        all_visible_categories = self.count_categories()[0]

        if categories == "random":
            categories = random.randrange(0, len(all_visible_categories))

        if categories == "all_selected":
            if self.ew.is_element_present(self.SELECT_ALL_UNCHECKED):
                self.ew.tap_element(self.SELECT_ALL_UNCHECKED)
            elif self.ew.is_element_present(self.SELECT_ALL_PART):
                self.ew.tap_element(self.SELECT_ALL_PART)
                self.ew.tap_element(self.SELECT_ALL_UNCHECKED)
        elif categories == "all_unselected":
            if self.ew.is_element_present(self.SELECT_ALL_CHECKED):
                self.ew.tap_element(self.SELECT_ALL_CHECKED)
            elif self.ew.is_element_present(self.SELECT_ALL_PART):
                self.ew.tap_element(self.SELECT_ALL_PART)
        elif isinstance(categories, int):
            if self.ew.is_element_present(self.SELECT_ALL_CHECKED):
                self.ew.tap_element(self.SELECT_ALL_CHECKED)
            elif self.ew.is_element_present(self.SELECT_ALL_PART):
                self.ew.tap_element(self.SELECT_ALL_PART)
            x = 0
            all_visible_categories = self.count_categories()[0]
            for i in all_visible_categories:
                x = x + 1
                if x <= categories:
                    self.ew.tap_element(i)

        if self.ew.is_element_present(self.SELECT_ALL_CHECKED):
            v_input = "All Expenses"
        else:
            v_input = str(len(self.count_categories()[1]))

        self.ew.tap_element(self.BACK_BUTTON)
        vr.validate_input_against_output(v_input, self.get_categories())

    def count_categories(self):
        """ Gets all visible, currently selected and non selected categories inside category picker
        :return: tuple of lists
        """
        if PLATFORM == "Android":
            all_visible_categories = self.ew.get_attributes(self.CATEGORY_ITEM, "content-desc")
        else:
            all_items = self.ew.get_attributes(self.CATEGORY_ITEM, "name")
            all_visible_categories = []
            for i in all_items:
                if i != "Category Item":
                    all_visible_categories.append(i)

        selected_categories = []
        non_selected_categories = []
        for i in all_visible_categories:
            if i.endswith('true'):
                selected_categories.append(i)
            else:
                non_selected_categories.append(i)
        return (all_visible_categories, selected_categories, non_selected_categories)

    def get_categories(self):
        """ Gets number of selected categories
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.CATEGORIES, 5)

        if PLATFORM == "Android":

            result = self.ew.get_text_of_element(self.SELECTED_CATEGORIES_ANDROID)
            if result is None:
                result = self.ew.get_text_of_element(self.SELECTED_CATEGORIES_ANDROID_2)
            return result
        else:
            return self.ew.get_attribute(self.CATEGORIES, "name")

    def set_recurrence(self, recurrence):
        """ Selects requested recurrence of budget
        :param recurrence: str
        """
        self.ew.wait_and_tap_element(self.RECURRENCE, 5)
        self.ew.wait_till_element_is_visible(self.RECURRENCE_PICKER, 5)

        if recurrence == "random":
            recurrence = random.choice(vs.budget_recurrences)

        res = self.rs.get_resolution()
        if PLATFORM == "Android":
            item_visible = self.ew.is_element_present(recurrence)
            while item_visible is False:
                self.action.long_press(None, self.rs.all_resolutions[f"{res}"]["x"],
                                       self.rs.all_resolutions[f"{res}"]["default_picker_up_y_start"]) \
                    .move_to(None, self.rs.all_resolutions[f"{res}"]["x"],
                             self.rs.all_resolutions[f"{res}"]["default_picker_up_y_end"]) \
                    .release().perform()
                item_visible = self.ew.is_element_present(recurrence)
            self.ew.wait_and_tap_element(recurrence, 5)
        else:
            item_visible = self.ew.get_attribute(recurrence, "visible")
            while item_visible == "false":
                self.driver.execute_script("mobile: dragFromToForDuration",
                                           {"duration": "0.1",
                                            "fromX": self.rs.all_resolutions[f"{res}"]["x"],
                                            "fromY": self.rs.all_resolutions[f"{res}"]["default_picker_up_y_start"],
                                            "toX": self.rs.all_resolutions[f"{res}"]["x"],
                                            "toY": self.rs.all_resolutions[f"{res}"]["default_picker_up_y_end"]})
                item_visible = self.ew.get_attribute(recurrence, "visible")
            self.driver.execute_script("mobile: tap", {"x": 100, "y": 50, "element": self.ew.get_element(recurrence)})

        vr.validate_input_against_output(recurrence, self.get_recurrence())

    def get_recurrence(self):
        """ Gets selected recurrence
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.RECURRENCE, 5)
        if PLATFORM == "Android":
            recurrence = self.ew.get_text_of_element(self.SELECTED_RECURRENCE_ANDROID)
            if recurrence is None:
                recurrence = self.ew.get_text_of_element(self.SELECTED_RECURRENCE_ANDROID_EDIT)
        else:
            recurrence = self.ew.get_attribute(self.RECURRENCE, "name")
        return recurrence

    def set_start_date(self, start_date):
        """ Selects start date of budget
        :param start_date: str
        """
        if start_date == "random":
            start_date = str(
                datetime.date(int(datetime.date.today().year), random.randint(1, 12), random.randint(1, 28)))
        elif start_date == "future":
            start_date = str(datetime.date.today() + datetime.timedelta(days=random.randint(1, 5)))
        elif start_date == "today":
            start_date = str(datetime.date.today())
        elif start_date == "yesterday":
            start_date = str(datetime.date.today() - datetime.timedelta(days=1))
        elif start_date == "tomorrow":
            start_date = str(datetime.date.today() + datetime.timedelta(days=1))

        self.ew.wait_and_tap_element(self.START_DATE, 5)
        self.ew.wait_till_element_is_visible(self.CALENDAR_PICKER, 5)
        self.transaction_detail.set_calendar_month_year(start_date)
        self.transaction_detail.set_calendar_day(start_date)
        vr.validate_input_against_output(start_date, self.transaction_detail.get_date("start"))

    def set_end_date(self, end_date):
        """ Selects end date of budget
        :param end_date: str
        """
        start_date = self.transaction_detail.get_date("start")
        year_start, month_start, day_start = (int(x) for x in start_date.split('-'))
        start_date = datetime.date(year_start, month_start, day_start)

        if end_date == "random":
            end_date = str(start_date + datetime.timedelta(days=random.randint(1, 30)))
        elif end_date == "day_after_start_date":
            end_date = str(start_date + datetime.timedelta(days=1))
        else:
            year_end, month_end, day_end = (int(x) for x in end_date.split('-'))
            end_date = datetime.date(year_end, month_end, day_end)
            if start_date < end_date:
                end_date = str(end_date)
            else:
                raise ValueError(f"endDate {end_date} is not older than start_date {str(start_date)}")

        self.ew.wait_and_tap_element(self.END_DATE, 5)
        self.ew.wait_till_element_is_visible(self.CALENDAR_PICKER, 5)
        self.transaction_detail.set_calendar_month_year(end_date)
        self.transaction_detail.set_calendar_day(end_date)

        vr.validate_input_against_output(end_date, self.transaction_detail.get_date("end"))
Пример #18
0
class TransactionValidator:
    def __init__(self, driver):
        self.driver = driver
        self.action = TouchAction(self.driver)
        self.ew = ElementWrapper(self.driver)
        self.period_filter = PeriodFilter(self.driver)
        self.rs = Resolutions(self.driver)
        self.timeline_general = TimelineGeneral(self.driver)
        self.transaction_detail = TransactionDetail(self.driver)

    def get_all_attributes(self):
        """ Getting all attributes of transaction
        :return: dict
        """
        all_attributes = {
            "category": self.transaction_detail.get_category(),
            "amount": self.transaction_detail.get_amount(),
            "wallet_amount": self.transaction_detail.get_wallet_amount(),
            "currency": self.transaction_detail.get_currency(),
            "wallet": self.transaction_detail.get_wallet("transaction"),
            "start_date": self.transaction_detail.get_date("start"),
            "note": self.transaction_detail.get_note(),
            "labels": self.transaction_detail.get_labels(True),
            "photo": self.transaction_detail.get_photo(),
            "reminder": self.transaction_detail.get_reminder(),
        }

        return all_attributes

    def is_transaction_on_timeline(self, attributes):
        """ Checking if transaction is visible inside Timeline or Scheduled section
        :param attributes: dict
        :return: bool
        """
        transaction_locator = f"regular/" \
                              f"{attributes['category']}/" \
                              f"{self.adjust_amounts(attributes['amount'], attributes['wallet_amount'])[0]}/" \
                              f"{self.adjust_amounts(attributes['amount'], attributes['wallet_amount'])[1]}/" \
                              f"{attributes['wallet']}/" \
                              f"undefined/" \
                              f"{self.adjust_note(attributes['note'])}/" \
                              f"{self.adjust_labels(attributes['labels'])}/" \
                              f"{str(attributes['photo']).lower()}/" \
                              f"undefined/" \
                              f"undefined/" \
                              f"{self.adjust_reminder(attributes['reminder'])}"

        print(f'LOCATOR: {transaction_locator}')

        self.prepare_timeline(attributes['start_date'], "undefined")

        android_timeout = time.time() + 60
        ios_timeout = time.time() + 5
        res = self.rs.get_resolution()
        is_transaction_present = self.ew.is_element_present(
            transaction_locator)

        while is_transaction_present is False:
            if PLATFORM == "Android":
                self.swipe_android(res)
                is_transaction_present = self.ew.is_element_present(
                    transaction_locator)
                if time.time() > android_timeout:
                    return False
            else:
                is_transaction_present = self.ew.is_element_present(
                    transaction_locator)
                if time.time() > ios_timeout:
                    return False
        return True

    def adjust_amounts(self, amount, wallet_amount):
        """ Adjusting amount for transaction locator
        :param amount: str
        :param wallet_amount: str
        :return: list of str
        """
        if wallet_amount is None:
            amount_final = amount
            wallet_amount_final = "undefined"
        else:
            amount_final = ""
            for i in wallet_amount:
                if i in [
                        "-", ".", "0", "1", "2", "3", "4", "5", "6", "7", "8",
                        "9"
                ]:
                    amount_final = amount_final + i

            wallet_amount_final = "{:.2f}".format(float(amount))
        return ["{:.2f}".format(float(amount_final)), wallet_amount_final]

    def adjust_note(self, note):
        """ Adjusting note for transaction locator
        :param note: str
        :return: str
        """
        if note is None:
            note = ""
        return note

    def adjust_labels(self, labels):
        """ Adjusting labels for transaction locator
        :param labels: list of str
        :return: list of str
        """
        if len(labels) > 0:
            labels_final = ""
            for i in labels:
                labels_final = labels_final + f",{i}"
            labels_final = labels_final[1:]
        else:
            labels_final = "undefined"

        return labels_final

    def adjust_reminder(self, reminder):
        """ Adjusting reminder for transaction locator
        :param reminder: str
        :return: str
        """
        if reminder is None or reminder == "Never":
            return "undefined"
        else:
            return reminder

    def prepare_timeline(self, start_date, recurrence):
        """ Prepares timeline for transaction search. Opening scheduled screen if transaction has future date.
        :param start_date: str
        :param recurrence: str
        """
        self.ew.wait_till_element_is_visible(
            self.timeline_general.NAVIGATION_TIMELINE, 30)
        year, month, day = (int(x) for x in start_date.split('-'))
        date = datetime.date(year, month, day)
        today = datetime.date.today()

        if date > today or recurrence != "undefined":

            if self.ew.is_element_present(
                    self.timeline_general.SCHEDULED_SCREEN) is False:
                self.ew.wait_till_element_is_visible(
                    self.timeline_general.TRANSACTION_SECTION, 20)
                self.timeline_general.open_scheduled_section()
            else:
                if PLATFORM == "Android":
                    time.sleep(5)
                else:
                    time.sleep(2)

        elif date < today:
            self.period_filter.set_filter_period(
                self.period_filter.ALL_TIME_PERIOD)

    def swipe_android(self, resolution):
        """ Looks into past by swiping on android phones
        :param resolution: str
        :return:
        """
        self.action.long_press(None, self.rs.all_resolutions[f"{resolution}"]["x"],
                               self.rs.all_resolutions[f"{resolution}"]["transaction_timeline_up_y_start"]) \
            .move_to(None, self.rs.all_resolutions[f"{resolution}"]["x"],
                     self.rs.all_resolutions[f"{resolution}"]["transaction_timeline_up_y_end"]) \
            .release().perform()
Пример #19
0
 def __init__(self, driver):
     self.driver = driver
     self.ew = ElementWrapper(self.driver)
Пример #20
0
class ExportActions:
    BACKDROP = "Backdrop"

    # WALLETS
    WALLETS = "Wallets"

    # PERIOD
    PERIOD = "Period"
    PERIOD_SIZE_PICKER = "Period size Picker"
    SELECT_DATE_RANGE_PICKER = "Select date range Picker"

    # FORMAT
    FORMAT = "Format"
    FORMAT_PICKER = "Format Picker"
    if PLATFORM == "Android":
        XLSX_TRUE = "Excel (.xlsx)-true"
    else:
        XLSX_TRUE = 'label == "Excel (.xlsx)-true"'

    def __init__(self, driver):
        self.driver = driver
        self.action = TouchAction(self.driver)
        self.ew = ElementWrapper(self.driver)
        self.rs = Resolutions(self.driver)

    def set_period(self, period):
        """ Selects period from period picker
        :param period: str
        """

        self.ew.wait_and_tap_element(self.PERIOD, 10)
        self.ew.wait_till_element_is_visible(self.PERIOD_SIZE_PICKER, 10)

        if period == "random":
            period = random.choice(vs.export_periods)

        res = self.rs.get_resolution()
        if PLATFORM == "Android":
            item_visible = self.ew.is_element_present(period)
            while item_visible is False:
                self.action.long_press(None, self.rs.all_resolutions[f"{res}"]["x"],
                                       self.rs.all_resolutions[f"{res}"]["default_picker_up_y_start"]) \
                    .move_to(None, self.rs.all_resolutions[f"{res}"]["x"],
                             self.rs.all_resolutions[f"{res}"]["default_picker_up_y_end"]) \
                    .release().perform()
                item_visible = self.ew.is_element_present(period)
            self.ew.wait_and_tap_element(period, 5)
        else:
            item_visible = self.ew.get_attribute(period, "visible")
            while item_visible == "false":
                self.driver.execute_script(
                    "mobile: dragFromToForDuration", {
                        "duration":
                        "0.1",
                        "fromX":
                        self.rs.all_resolutions[f"{res}"]["x"],
                        "fromY":
                        self.rs.all_resolutions[f"{res}"]
                        ["default_picker_up_y_start"],
                        "toX":
                        self.rs.all_resolutions[f"{res}"]["x"],
                        "toY":
                        self.rs.all_resolutions[f"{res}"]
                        ["default_picker_up_y_end"]
                    })
                item_visible = self.ew.get_attribute(period, "visible")
            self.driver.execute_script("mobile: tap", {
                "x": 100,
                "y": 50,
                "element": self.ew.get_element(period)
            })

    def set_format(self, format):
        """ Selects format of file from format picker
        :param format: str
        """

        self.ew.wait_and_tap_element(self.FORMAT, 10)
        self.ew.wait_till_element_is_visible(self.FORMAT_PICKER, 10)

        if format == "random":
            format = random.choice(vs.export_formats)

        self.ew.wait_and_tap_element(format, 5)
Пример #21
0
class BudgetActions():
    def __init__(self, driver):
        self.driver = driver
        self.action = TouchAction(self.driver)
        self.budgets_general = BudgetsGeneral(self.driver)
        self.budget_detail = BudgetDetail(self.driver)
        self.budget_overview = BudgetOverview(self.driver)
        self.ew = ElementWrapper(self.driver)
        self.rs = Resolutions(self.driver)

    def create_budget(self, name, amount, currency, wallets, categories,
                      recurrence, start_date, end_date):
        """ Opens budget create screen and sets requested attributes of budget
        :param name: str
        :param amount: str
        :param currency: str or None
        :param wallets: str or int or None
        :param categories: str or int or None
        :param recurrence: str or None
        :param start_date: str or None
        :param end_date: str or None
        """
        self.budgets_general.go_to_budgets()
        self.open_budget_create_screen()
        self.budget_detail.set_name(name)
        self.budget_detail.set_amount(amount)
        if currency is not None:
            self.budget_detail.set_currency(currency)
        if wallets is not None:
            self.budget_detail.set_wallets(wallets)
        if categories is not None:
            self.budget_detail.set_categories(categories)
        if recurrence is not None:
            self.budget_detail.set_recurrence(recurrence)
        if start_date is not None:
            self.budget_detail.set_start_date(start_date)
        if end_date is not None:
            self.budget_detail.set_end_date(end_date)

    def save_budget(self):
        """Clicks on save budget button"""
        if self.driver.is_keyboard_shown():
            self.driver.hide_keyboard()
        self.ew.wait_and_tap_element(self.budget_detail.SAVE_BUDGET_BUTTON, 10)
        self.ew.wait_till_element_is_not_visible(
            self.budget_detail.SAVE_BUDGET_BUTTON, 10)

    def open_budget_create_screen(self):
        """Opens budget create screen, if button is not visible it swipes to it"""
        self.ew.wait_till_element_is_visible(
            self.budgets_general.BUDGETS_HEADER, 10)
        if PLATFORM == "Android":
            add_button_visible = self.ew.is_element_present(
                self.budgets_general.ADD_BUDGET_BUTTON)
            while add_button_visible is False:
                res = self.rs.get_resolution()
                self.action.long_press(None, self.rs.all_resolutions[f"{res}"]["x"],
                                       self.rs.all_resolutions[f"{res}"]["budget_overview_y_start"]) \
                    .move_to(None, self.rs.all_resolutions[f"{res}"]["x"],
                             self.rs.all_resolutions[f"{res}"]["budget_overview_y_end"]) \
                    .release().perform()
                add_button_visible = self.ew.is_element_present(
                    self.budgets_general.ADD_BUDGET_BUTTON)
        else:
            add_button_visible = self.ew.get_attribute(
                self.budgets_general.ADD_BUDGET_BUTTON, "visible")
            while add_button_visible == "false":
                res = self.rs.get_resolution()
                self.driver.execute_script(
                    "mobile: dragFromToForDuration", {
                        "duration":
                        "0.1",
                        "fromX":
                        self.rs.all_resolutions[f"{res}"]["x"],
                        "fromY":
                        self.rs.all_resolutions[f"{res}"]
                        ["budget_overview_y_start"],
                        "toX":
                        self.rs.all_resolutions[f"{res}"]["x"],
                        "toY":
                        self.rs.all_resolutions[f"{res}"]
                        ["budget_overview_y_end"]
                    })
                add_button_visible = self.ew.get_attribute(
                    self.budgets_general.ADD_BUDGET_BUTTON, "visible")

        self.ew.wait_and_tap_element(self.budgets_general.ADD_BUDGET_BUTTON, 5)
        self.ew.wait_till_element_is_visible(self.budget_detail.BUDGET_HEADER,
                                             10)

    def open_budget(self):
        """Opens existing budget detail screen, if there is no budget created yet, it creates one"""
        self.budgets_general.go_to_budgets()
        self.ew.wait_till_element_is_visible(
            self.budgets_general.BUDGETS_HEADER, 5)
        if self.ew.is_element_present(
                self.budgets_general.BUDGET_ITEM) is False:
            self.create_budget(name="random",
                               amount="random",
                               currency=None,
                               wallets=None,
                               categories=None,
                               recurrence=None,
                               start_date=None,
                               end_date=None)
            self.save_budget()
            self.budgets_general.go_to_budgets()
        self.ew.wait_and_tap_element(self.budgets_general.BUDGET_ITEM, 5)
        self.ew.wait_and_tap_element(
            self.budget_overview.BUDGET_SETTINGS_BUTTON, 5)
        self.ew.wait_till_element_is_visible(self.budget_detail.BUDGET_HEADER,
                                             5)

    def edit_budget(self, name, amount, currency, wallets, categories,
                    recurrence, start_date, end_date):
        """ Opens budget edit screen and sets requested attributes of budget
        :param name: str or None
        :param amount: str or None
        :param currency: str or None
        :param wallets: str or int or None
        :param categories:  str or int or None
        :param recurrence: str or None
        :param start_date: str or None
        :param end_date: str or None
        """
        self.open_budget()
        if name is not None:
            if PLATFORM == "Android":
                self.ew.get_element(self.budget_detail.NAME_INPUT).clear()
            else:
                self.ew.get_element(
                    self.budget_detail.SELECTED_NAME_IOS).clear()
            self.budget_detail.set_name(name)
        if amount is not None:
            self.ew.wait_and_tap_element(self.budget_detail.AMOUNT_INPUT, 5)
            self.ew.wait_till_element_is_visible(
                self.budget_detail.NUMPAD_CLEAR, 10)
            for i in range(6):
                self.ew.tap_element(self.budget_detail.NUMPAD_CLEAR)
            self.ew.tap_element(self.budget_detail.NUMPAD_BACKDROP)
            self.budget_detail.set_amount(amount)
        if currency is not None:
            self.budget_detail.set_currency(currency)
        if wallets is not None:
            self.budget_detail.set_wallets(wallets)
        if categories is not None:
            self.budget_detail.set_categories(categories)
        if recurrence is not None:
            self.budget_detail.set_recurrence(recurrence)
        if start_date is not None:
            self.budget_detail.set_start_date(start_date)
        if end_date is not None:
            self.budget_detail.set_end_date(end_date)

    def delete_budget(self):
        """Deletes existing budget from budget detail screen"""
        self.ew.wait_and_tap_element(self.budget_detail.TRASH_ICON, 10)
        self.ew.wait_and_tap_element(self.budget_detail.DELETE_BUTTON, 10)
        self.ew.wait_till_element_is_visible(
            self.budgets_general.BUDGETS_HEADER, 10)
Пример #22
0
class MarketingDialog:
    MARKETING_DIALOG = "Marketing Dialog"
    AGREE_BUTTON = "Agree"
    DISAGREE_BUTTON = "Don't Agree"
    ALLOW_BUTTON = 'Allow'

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def agree_with_marketing(self):
        """Clicks on agree button on marketing dialog"""
        self.ew.wait_till_element_is_visible(self.MARKETING_DIALOG, 20)
        self.ew.wait_and_tap_element(self.AGREE_BUTTON, 5)

    def disagree_with_marketing(self):
        """Clicks on disagree button on marketing dialog"""
        self.ew.wait_till_element_is_visible(self.MARKETING_DIALOG, 20)
        self.ew.wait_and_tap_element(self.DISAGREE_BUTTON, 5)

    def agree_with_ios_notifications(self):
        """Clicks on agree button on ios notifications dialog"""
        if self.ew.is_element_present(self.ALLOW_BUTTON):
            self.ew.wait_and_tap_element(self.ALLOW_BUTTON, 30)
Пример #23
0
class CategoryActions:
    def __init__(self, driver):
        self.driver = driver
        self.category_detail = CategoryDetail(self.driver)
        self.categories_general = CategoriesGeneral(self.driver)
        self.ew = ElementWrapper(self.driver)
        self.more_general = MoreGeneral(self.driver)

    def open_category_create_screen(self):
        """Opens category create screen"""
        self.ew.wait_and_tap_element(
            self.categories_general.ADD_CATEGORY_BUTTON, 10)
        self.ew.wait_till_element_is_visible(
            self.category_detail.CATEGORY_HEADER, 10)

    def open_category(self):
        """Opens detail of category"""
        if self.ew.is_element_present(
                self.categories_general.CATEGORY_ITEM) is False:
            self.create_category(type_of_category="random",
                                 name="random",
                                 color="random",
                                 image="random")
            self.save_category()

        self.ew.wait_and_tap_element(self.categories_general.CATEGORY_ITEM, 10)
        self.ew.wait_till_element_is_visible(
            self.category_detail.CATEGORY_HEADER, 10)

    def create_category(self, type_of_category, name, color, image):
        """ Sets requested parameters of category inside category detail
        :param type_of_category: str
        :param name: str
        :param color: str
        :param image: str or int
        :return:
        """
        self.categories_general.set_type(type_of_category)
        self.open_category_create_screen()
        self.category_detail.set_name(name)
        self.category_detail.set_color(color)
        self.category_detail.set_image(image)

    def save_category(self):
        """Clicks on save category button"""
        self.ew.wait_and_tap_element(self.category_detail.SAVE_CATEGORY_BUTTON,
                                     10)
        self.ew.wait_till_element_is_visible(
            self.more_general.CATEGORIES_HEADER, 10)

    def confirm_merge(self):
        """Confirms merge of categories"""
        self.ew.wait_and_tap_element(
            self.categories_general.MERGE_CATEGORIES_BUTTON, 10)
        self.ew.wait_and_tap_element(
            self.categories_general.CONFIRM_MERGE_BUTTON, 10)
        self.ew.wait_till_element_is_visible(
            self.more_general.CATEGORIES_HEADER, 10)

    def edit_category(self, type_of_category, name, color, image):
        """ Sets requested attributes inside category detail
        :param type_of_category: str or None
        :param name: str or None
        :param color: str or None
        :param image: str or int or None
        """
        self.categories_general.set_type(type_of_category)
        self.open_category()
        if name is not None:
            self.category_detail.set_name(name)
        if color is not None:
            self.category_detail.set_color(color)
        if image is not None:
            self.category_detail.set_image(image)

    def delete_category(self):
        """Deletes category"""
        self.ew.wait_and_tap_element(self.category_detail.TRASH_ICON, 10)
        self.ew.wait_and_tap_element(self.category_detail.DELETE_BUTTON, 10)
        self.ew.wait_till_element_is_visible(
            self.more_general.CATEGORIES_HEADER, 10)

    def merge_categories(self):
        """Selects 2 visible categories"""
        self.ew.wait_and_tap_element(
            self.categories_general.MERGE_CATEGORIES_BUTTON, 10)
        all_visible_categories = self.ew.get_attributes(
            self.categories_general.CATEGORY_INFO, "content-desc")
        self.ew.tap_element(all_visible_categories[0])
        self.ew.tap_element(all_visible_categories[1])
Пример #24
0
class TransactionTemplateValidator:
    def __init__(self, driver):
        self.driver = driver
        self.action = TouchAction(self.driver)
        self.ew = ElementWrapper(self.driver)
        self.period_filter = PeriodFilter(self.driver)
        self.rs = Resolutions(self.driver)
        self.timeline_general = TimelineGeneral(self.driver)
        self.transaction_detail = TransactionDetail(self.driver)
        self.transaction_validator = TransactionValidator(self.driver)

    def get_all_attributes(self):
        """ Getting all attributes of transaction template
        :return: dict
        """
        all_attributes = {
            "category": self.transaction_detail.get_category(),
            "amount": self.transaction_detail.get_amount(),
            "wallet_amount": self.transaction_detail.get_wallet_amount(),
            "currency": self.transaction_detail.get_currency(),
            "wallet": self.transaction_detail.get_wallet("transaction"),
            "start_date": self.transaction_detail.get_date("start"),
            "note": self.transaction_detail.get_note(),
            "labels": self.transaction_detail.get_labels(True),
            "photo": self.transaction_detail.get_photo(),
            "recurrence": self.transaction_detail.get_recurrence(),
            "end_date": self.transaction_detail.get_date("end"),
            "reminder": self.transaction_detail.get_reminder(),
        }

        return all_attributes

    def is_transaction_template_on_timeline(self, attributes):
        """ Checking if template is visible inside Scheduled section
        :param attributes: dict
        :return: bool
        """
        transaction_locator = f"regular/" \
                              f"{attributes['category']}/" \
                              f"{self.transaction_validator.adjust_amounts(attributes['amount'], attributes['wallet_amount'])[0]}/" \
                              f"{self.transaction_validator.adjust_amounts(attributes['amount'], attributes['wallet_amount'])[1]}/" \
                              f"{attributes['wallet']}/" \
                              f"undefined/" \
                              f"{self.transaction_validator.adjust_note(attributes['note'])}/" \
                              f"{self.transaction_validator.adjust_labels(attributes['labels'])}/" \
                              f"{str(attributes['photo']).lower()}/" \
                              f"{self.adjust_recurrence(attributes['recurrence'])}/" \
                              f"{self.adjust_end_date(attributes['end_date'])}/" \
                              f"{self.transaction_validator.adjust_reminder(attributes['reminder'])}"

        print(f'LOCATOR: {transaction_locator}')

        self.transaction_validator.prepare_timeline(
            attributes['start_date'],
            self.adjust_recurrence(attributes['recurrence']))

        android_timeout = time.time() + 60
        ios_timeout = time.time() + 5
        res = self.rs.get_resolution()
        is_transaction_present = self.ew.is_element_present(
            transaction_locator)

        while is_transaction_present is False:
            if PLATFORM == "Android":
                self.transaction_validator.swipe_android(res)
                is_transaction_present = self.ew.is_element_present(
                    transaction_locator)
                if time.time() > android_timeout:
                    return False
            else:
                is_transaction_present = self.ew.is_element_present(
                    transaction_locator)
                if time.time() > ios_timeout:
                    return False
        return True

    def adjust_recurrence(self, recurrence):
        """ Adjusting recurrence for template locator
        :param recurrence: str
        :return: str
        """
        if recurrence is None or recurrence == "never":
            return "undefined"
        else:
            return recurrence

    def adjust_end_date(self, end_date):
        """ Adjusting end date for template locator
        :param end_date: str
        :return: str
        """
        if end_date is None:
            return "undefined"
        else:
            return end_date
Пример #25
0
class WelcomeScreen:
    WELCOME_SCREEN = "Welcome Screen"
    SIGN_UP_WITH_EMAIL_BUTTON = "Sign Up With Email"
    LOGIN_WITH_EMAIL_BUTTON = "Login With Email"
    SIGN_IN_WITH_GOOGLE_BUTTON = "Sign In With Google"
    SIGN_IN_WITH_FACEBOOK = "Sign In With Facebook"
    SIGN_IN_WITH_APPLE = "Sign In With Apple"
    NOTIFICATIONS_ALERT = '“Spendee” Would Like to Send You Notifications'
    ALLOW_NOTIFICATIONS_BUTTON = "Allow"
    ALLOW_FB_LOGIN_BUTTON = 'label == "Continue"'

    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)

    def open_sign_up_email_screen(self):
        """Opens sign up screen for registration via email and password"""
        self.ew.wait_and_tap_element(self.SIGN_UP_WITH_EMAIL_BUTTON, 30)

    def open_login_by_email_screen(self):
        """Opens login screen for login via email and password"""
        self.ew.wait_and_tap_element(self.LOGIN_WITH_EMAIL_BUTTON, 30)

    def open_login_by_facebook(self):
        """Opens sign in screen of Facebook OAuth"""
        self.ew.wait_and_tap_element(self.SIGN_IN_WITH_FACEBOOK, 30)
        if PLATFORM == "iOS":
            self.ew.wait_and_tap_element(self.ALLOW_FB_LOGIN_BUTTON, 15)

    def open_login_by_google(self):
        """Opens sign in screen of Google OAuth"""
        self.ew.wait_and_tap_element(self.SIGN_IN_WITH_GOOGLE_BUTTON, 30)
        if PLATFORM == "iOS":
            self.ew.wait_and_tap_element(self.ALLOW_FB_LOGIN_BUTTON, 15)

    def skip_notifications_alert(self):
        """Allows notifications on iOS if the dialog is present"""
        try:
            self.ew.wait_till_element_is_visible(self.WELCOME_SCREEN, 1)
        except NoSuchElementException:
            pass
        if PLATFORM == "iOS" and self.ew.is_element_present(self.NOTIFICATIONS_ALERT):
            self.ew.tap_element(self.ALLOW_NOTIFICATIONS_BUTTON)
Пример #26
0
 def __init__(self, driver):
     self.driver = driver
     self.action = TouchAction(self.driver)
     self.ew = ElementWrapper(self.driver)
     self.rs = Resolutions(self.driver)
Пример #27
0
 def __init__(self, driver):
     self.driver = driver
     self.ew = ElementWrapper(self.driver)
     self.export_general = ExportGeneral(self.driver)
Пример #28
0
 def __init__(self, driver):
     self.driver = driver
     self.action = TouchAction(self.driver)
     self.ew = ElementWrapper(self.driver)
     self.rs = Resolutions(self.driver)
     self.transaction_detail = TransactionDetail(self.driver)
Пример #29
0
 def __init__(self, driver):
     self.driver = driver
     self.category_detail = CategoryDetail(self.driver)
     self.categories_general = CategoriesGeneral(self.driver)
     self.ew = ElementWrapper(self.driver)
     self.more_general = MoreGeneral(self.driver)
Пример #30
0
class AuthenticationActions:
    def __init__(self, driver):
        self.driver = driver
        self.ew = ElementWrapper(self.driver)
        self.email_password = EmailPassword(self.driver)
        self.facebook = Facebook(self.driver)
        self.google = Google(self.driver)
        self.marketing_dialog = MarketingDialog(self.driver)
        self.more_general = MoreGeneral(self.driver)
        self.timeline_general = TimelineGeneral(self.driver)
        self.user_profile = UserProfile(self.driver)
        self.welcome_screen = WelcomeScreen(self.driver)

    def register_by_email(self, email, password):
        """ Goes through registration process by email and password
        :param email: str
        :param password: str
        """
        self.welcome_screen.open_sign_up_email_screen()
        self.email_password.set_email(email)
        self.email_password.set_password(password)
        self.ew.tap_element(self.email_password.SIGN_UP_BUTTON)
        time.sleep(0.5)
        if PLATFORM == "iOS":
            self.marketing_dialog.agree_with_ios_notifications()

    def login_by_facebook(self, email, password):
        """ Goes through sign in process by Facebook
        :param email: str
        :param password: str
        """
        self.welcome_screen.open_login_by_facebook()
        self.ew.wait_till_element_is_visible(self.facebook.FACEBOOK_HEADER, 30)
        if self.ew.is_element_present(self.facebook.COOKIES_ACCEPT_BUTTON):
            self.ew.tap_element(self.facebook.COOKIES_ACCEPT_BUTTON)
        self.ew.get_element(self.facebook.EMAIL_TEXT_BOX).send_keys(email)
        self.ew.get_element(
            self.facebook.PASSWORD_TEXT_BOX).send_keys(password)
        self.ew.wait_and_tap_element(self.facebook.LOGIN_BUTTON, 10)
        self.ew.wait_and_tap_element(self.facebook.CONTINUE_BUTTON, 20)
        if PLATFORM == "iOS":
            self.marketing_dialog.agree_with_ios_notifications()

    def login_by_email(self, email, password):
        """ Goes through login process by email and password
        :param email: str
        :param password: str
        """
        self.welcome_screen.open_login_by_email_screen()
        self.email_password.set_email(email)
        self.email_password.set_password(password)
        self.ew.tap_element(self.email_password.LOGIN_BUTTON)
        if PLATFORM == "iOS":
            self.marketing_dialog.agree_with_ios_notifications()

    def login_by_google(self):
        """Goes through sign in process by Google, when user was previously logged on device"""
        self.welcome_screen.open_login_by_google()
        self.ew.wait_and_tap_element(self.google.EMAIL_TO_SELECT, 20)

    def logout(self):
        """Logouts user from the application"""
        self.more_general.go_to_more_section()
        self.ew.swipe_if_element_not_present(self.more_general.LOGOUT_BUTTON)
        self.ew.tap_element(self.more_general.LOGOUT_BUTTON)