Beispiel #1
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")
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()
Beispiel #3
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
Beispiel #4
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()
Beispiel #5
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"))
Beispiel #6
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)
Beispiel #7
0
class WalletDetail:
    # OTHER
    WALLET_HEADER = "Wallet Header"
    SAVE_WALLET_BUTTON = "Save Wallet 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
    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 Subtraction"
    }
    NUMPAD_BACKDROP = "Numpad Backdrop"
    NUMPAD_CLEAR = "Numpad Clear"

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

    # 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"'

    # CATEGORIES

    CATEGORIES_HEADER = "Categories Header"
    BACK_BUTTON = "Back Button"
    EYE_ICON = "Eye Icon"
    if PLATFORM == "Android":
        CATEGORIES = "Categories"
        EYE_ICON = "Eye Icon"
        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:
        CATEGORIES = 'label == "Categories"'
        EYE_ICON = 'label == "Eye Icon"'

    # SHARING
    SHARE_WALLET_BUTTON = "Share Wallet Button"
    if PLATFORM == "Android":
        DENY_BUTTON = 'com.android.packageinstaller:id/permission_deny_button'
    else:
        DENY_BUTTON = 'Don’t Allow'

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

    def set_name(self, name):
        """ Inserting 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)

        if self.driver.is_keyboard_shown():
            self.driver.hide_keyboard()

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

    def get_name(self):
        """ Getting name 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):
        """ Inserting amount into balance input
        :param amount: str
        """
        if amount == "random":
            amount = str(random.randint(-99, 99))
        elif amount == "random_positive":
            amount = str(random.randint(1, 99))
        elif amount == "random_negative":
            amount = str(random.randint(-99, -1))

        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):
        """ Getting amount from balance 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):
        """ Selecting currency of wallet
        :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):
        """ Getting selected currency of wallet
        :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_categories(self, categories):
        """ Selecting visible categories of wallet
        :param categories: "random" or int
        """
        if PLATFORM == "Android":
            v_input = self.get_categories()

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

            if categories == "random":
                categories = random.randint(1, 5)

            visible_categories = self.ew.get_elements(self.EYE_ICON)
            x = 0
            for i in visible_categories:
                x = x + 1
                if x <= categories:
                    i.click()

            self.ew.wait_and_tap_element(self.BACK_BUTTON, 5)
            vr.validate_input_against_output(
                int(v_input) - categories, int(self.get_categories()))

    def get_categories(self):
        """ Getting number of visible categories of wallet
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.CATEGORIES, 5)
        time.sleep(1)

        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 invite_user(self):
        """Opening invitation screen"""
        self.ew.wait_and_tap_element(self.SHARE_WALLET_BUTTON, 15)
class TransactionDetail:
    # OTHER
    BACK_BUTTON = "Back Button"
    if PLATFORM == "Android":
        TRANSACTION_HEADER_TITLE = "Transaction Header Title"
    else:
        TRANSACTION_HEADER_TITLE = '**/XCUIElementTypeStaticText[`label == "Transaction Header Title"`]'
    SAVE_TRANSACTION_BUTTON = "Save Transaction Button"
    TRASH_ICON = "Trash Icon"
    DELETE_BUTTON = "Delete"

    # 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"

    # TYPE AND CATEGORY
    CATEGORY_ICON = "Category Icon"
    EXPENSES_PICKER = "Expenses Picker"
    INCOME_PICKER = "Income Picker"
    TRANSACTION_PICKER = "Transaction Picker"
    TRANSFER_PICKER = "Transfer Picker"
    if PLATFORM == "Android":
        SELECTED_TYPE = "Selected Type"
    else:
        SELECTED_TYPE = '**/XCUIElementTypeStaticText[`label == "Selected Type"`]'
    GEAR_ICON = "Gear Icon"
    CONFIRM_CATEGORY_ICON = "Confirm Category Icon"

    # AMOUNT
    if PLATFORM == "Android":
        AMOUNT_INPUT = "//android.view.ViewGroup[@content-desc='Amount Input']/android.view.ViewGroup/android.widget.TextView"
        WALLET_AMOUNT = "//android.view.ViewGroup[@content-desc='Wallet Price']/android.widget.TextView"
    else:
        AMOUNT_INPUT = 'label == "Amount Input"'
        WALLET_AMOUNT = "//XCUIElementTypeOther[@name='Wallet Price']/XCUIElementTypeStaticText"

    # CURRENCY
    CONFIRM_BUTTON = "Confirm Button"
    if PLATFORM == "Android":
        CURRENCY = "Currency"
    else:
        CURRENCY = "(//XCUIElementTypeOther[@name='Currency'])[1]/XCUIElementTypeOther"
    SELECTED_CURRENCY_ANDROID = "//android.view.ViewGroup[@content-desc='Currency']/android.widget.TextView"

    # WALLET
    if PLATFORM == "Android":
        WALLET = "Wallet"
        OUTGOING_WALLET = "Outgoing Wallet"
        INCOMING_WALLET = "Incoming Wallet"
        WALLET_ITEM = '//android.view.ViewGroup[@content-desc="Select Wallet Picker"]/android.widget.ScrollView/' \
                      'android.view.ViewGroup/android.widget.ScrollView/android.view.ViewGroup/android.view.ViewGroup'
    else:
        WALLET = 'label == "Wallet"'
        OUTGOING_WALLET = 'label == "Outgoing Wallet"'
        INCOMING_WALLET = 'label == "Incoming Wallet"'
        WALLET_ITEM = "Wallet Item"
    WALLET_PICKER = "Select Wallet Picker"

    SELECTED_WALLET_ANDROID = "//android.view.ViewGroup[@content-desc='Wallet']//android.widget.TextView[2]"
    SELECTED_OUTGOING_WALLET_ANDROID = "//android.view.ViewGroup[@content-desc='Outgoing Wallet']//android.widget.TextView[2]"
    SELECTED_INCOMING_WALLET_ANDROID = "//android.view.ViewGroup[@content-desc='Incoming Wallet']//android.widget.TextView[2]"

    # START DATE
    CALENDAR_PICKER = "Select date Picker"
    SELECTED_START_DATE_ANDROID = "//android.view.ViewGroup[@content-desc='Start Date']/android.view.ViewGroup/android.widget.TextView"
    SELECTED_START_DATE_ANDROID_2 = "//android.view.ViewGroup[@content-desc='Start Date']/android.widget.TextView"
    SELECTED_END_DATE_ANDROID = "//android.view.ViewGroup[@content-desc='End Date']/android.view.ViewGroup/android.widget.TextView[2]"
    SELECTED_END_DATE_ANDROID_2 = "//android.view.ViewGroup[@content-desc='End Date']/android.widget.TextView[2]"
    SELECTED_START_DATE_ANDROID_BUDGET = '//android.view.ViewGroup[@content-desc="Start Date"]/android.view.ViewGroup/android.widget.TextView[2]'
    SELECTED_START_DATE_ANDROID_BUDGET_2 = '//android.view.ViewGroup[@content-desc="Start Date"]/android.widget.TextView[2]'
    SELECTED_END_DATE_ANDROID_BUDGET = '//android.view.ViewGroup[@content-desc="End Date"]/android.view.ViewGroup/android.widget.TextView[2]'
    SELECTED_END_DATE_ANDROID_BUDGET_2 = '//android.view.ViewGroup[@content-desc="End Date"]/android.widget.TextView[2]'
    if PLATFORM == "Android":
        START_DATE = "Start Date"
        ACTUAL_MONTH_YEAR = "//android.widget.SeekBar/android.widget.TextView"
    else:
        START_DATE = 'label == "Start Date"'
        ACTUAL_MONTH_YEAR = "(//XCUIElementTypeOther[@name='Select date Picker']//XCUIElementTypeOther[contains(@name,'undefined')])[2]"

    # NOTE
    if PLATFORM == "Android":
        NOTE = "Note"
        EXISTING_NOTE = "Note"
    else:
        NOTE = "//XCUIElementTypeTextView[@name='Note Write a note']"
        EXISTING_NOTE = '**/XCUIElementTypeTextView[`label == "Note"`]'
    SELECTED_NOTE_IOS = "Note"
    NOTE_ELEMENT = "Note Element"

    # LABELS
    LABELS = "Labels"
    LABEL_ITEM = "Label Item"
    if PLATFORM == "Android":
        LABEL_INPUT = "//android.widget.EditText"
    else:
        LABEL_INPUT = "//XCUIElementTypeTextField"
    NON_EXISTING_LABEL = "Non Existing Label"
    VISIBLE_LABELS_ANDROID = "//android.view.ViewGroup[@content-desc='Label Item']/android.widget.TextView"
    VISIBLE_LABELS_IOS = "//XCUIElementTypeOther[@name='Label Item']/XCUIElementTypeOther"
    SELECTED_LABELS_ANDROID = "//android.view.ViewGroup[@content-desc='Check Mark']/android.view.ViewGroup/ancestor::*[1]/following-sibling::*[1]"
    PREMIUM_LABEL_ALERT = "Premium Label Alert"
    NOT_NOW_BUTTON = "Now now"

    # PHOTO
    PHOTO = "Photo"
    SELECTED_PHOTO = "Selected Photo"
    if PLATFORM == "Android":
        CHOOSE_PHOTO = "//android.widget.TextView[2]"
        PHOTO_FOLDER = "//android.widget.RelativeLayout"
        PHOTO_ITEM = "(//android.support.v7.widget.RecyclerView/android.view.ViewGroup)[1]"
    else:
        CHOOSE_PHOTO = "Choose from Library…"
        PHOTO_FOLDER = "All Photos"
        PHOTO_ITEM = "(//XCUIElementTypeImage)[1]"
    ALLOW_PHOTO_ACCESS_ANDROID = "com.android.packageinstaller:id/permission_allow_button"

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

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

    # REMINDER
    if PLATFORM == "Android":
        REMINDER = "Reminder"
    else:
        REMINDER = 'label == "Reminder"'
    REMINDER_PICKER = "Reminder Picker"
    SELECTED_REMINDER_ANDROID = "//android.view.ViewGroup[@content-desc='Reminder']/android.view.ViewGroup/android.widget.TextView[2]"

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

    def set_type_of_transaction(self, transaction_type):
        """ Selects type of transaction
        :param transaction_type: str
        """
        if transaction_type == "random":
            transaction_type = random.choice(
                [self.EXPENSES_PICKER, self.INCOME_PICKER])
        elif transaction_type == "opposite":
            actual_type = self.get_type_of_transaction()
            if actual_type == "Expenses":
                transaction_type = self.INCOME_PICKER
            else:
                transaction_type = self.EXPENSES_PICKER
        elif transaction_type == "expenses":
            transaction_type = self.EXPENSES_PICKER
        elif transaction_type == "income":
            transaction_type = self.INCOME_PICKER

        if transaction_type == self.EXPENSES_PICKER:
            v_input = "Expenses"
        else:
            v_input = "Income"

        self.ew.wait_and_tap_element(transaction_type, 5)
        if PLATFORM == "Android":
            time.sleep(0.5)

        vr.validate_input_against_output(v_input,
                                         self.get_type_of_transaction())

    def get_type_of_transaction(self):
        """ Gets type of transaction
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.SELECTED_TYPE, 5)
        if PLATFORM == "Android":
            return self.ew.get_text_of_element(self.SELECTED_TYPE)
        else:
            return self.ew.get_attribute(self.SELECTED_TYPE, "name")

    def set_type_to_transfer(self):
        """Will select type as transfer"""
        self.ew.wait_and_tap_element(self.TRANSFER_PICKER, 5)

        self.ew.wait_till_element_is_not_visible(self.TRANSFER_PICKER, 5)
        if self.ew.is_element_present(self.NUMPAD_BACKDROP):
            pass
        else:
            vr.validate_input_against_output("Transfer", self.get_category())

    def open_type_picker(self):
        """Opens type picker"""
        self.ew.wait_and_tap_element(self.CATEGORY_ICON, 10)

    def set_category(self, category):
        """ Selects category from category picker
        :param category: str
        """
        self.ew.wait_till_element_is_visible(self.TRANSACTION_PICKER, 5)
        if category == "random":
            category_visible = False
            timeout = time.time() + 15
            while category_visible is False:
                category = random.choice(vs.default_set_of_categories)
                category_visible = self.ew.is_element_present(
                    f"Category {category}")
                if time.time() > timeout:
                    break

        self.ew.tap_element(f"Category {category}")

        self.ew.wait_till_element_is_not_visible(self.TRANSACTION_PICKER, 5)
        if self.ew.is_element_present(self.NUMPAD_BACKDROP):
            pass
        else:
            vr.validate_input_against_output(category, self.get_category())

    def get_category(self):
        """ Gets selected category
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.TRANSACTION_HEADER_TITLE, 5)
        if PLATFORM == "Android":
            category = self.ew.get_text_of_element(
                self.TRANSACTION_HEADER_TITLE).split(" ")[1:]
        else:
            category = self.ew.get_attribute(self.TRANSACTION_HEADER_TITLE,
                                             "name").split(" ")[1:]
        return ' '.join(category)

    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_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)

        v_output = self.get_amount()
        if v_output.startswith("-"):
            v_output = v_output[1:]
        vr.validate_input_against_output(''.join(str(i) for i in amount_list),
                                         v_output)

    def get_amount(self):
        """ Gets amount from amount picker
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.AMOUNT_INPUT, 5)
        if PLATFORM == "Android":
            return self.ew.get_text_of_element(self.AMOUNT_INPUT)
        else:
            amount = self.ew.get_attribute(self.AMOUNT_INPUT, "name")
            if amount.startswith("+"):
                amount = amount[1:]
            return amount

    def get_wallet_amount(self):
        """ Gets wallet's amount when category has different currency
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.AMOUNT_INPUT, 5)
        try:
            if PLATFORM == "Android":
                return self.ew.get_text_of_element(self.WALLET_AMOUNT)
            else:
                return self.ew.get_attribute(self.WALLET_AMOUNT, "name")
        except NoSuchElementException:
            return None

    def set_currency(self, currency):
        """ Selects currency
        :param currency: str
        """
        if currency == "random":
            currency = random.choice(vs.accessible_currencies)
        self.ew.wait_and_tap_element(self.CURRENCY, 5)
        self.ew.wait_and_tap_element(f"Currency {currency}", 10)
        self.set_exchange_rate()

        vr.validate_input_against_output(currency, self.get_currency())

    def get_currency(self):
        """ Gets selected currency
        :return: str
        """
        self.ew.wait_till_element_is_visible(self.CURRENCY, 5)
        if PLATFORM == "Android":
            return self.ew.get_attribute(self.SELECTED_CURRENCY_ANDROID,
                                         "content-desc")
        else:
            return self.ew.get_attribute(self.CURRENCY, "name")

    def set_exchange_rate(self):
        self.ew.wait_and_tap_element(self.CONFIRM_BUTTON, 10)

    def set_wallet(self, wallet, type_of_wallet):
        """ Selects requested wallet from requested wallet picker
        :param wallet: str
        :param type_of_wallet: str
        """
        selected_wallet = self.get_wallet(type_of_wallet)
        if type_of_wallet == "transaction":
            self.ew.wait_and_tap_element(self.WALLET, 5)
        elif type_of_wallet == "transfer_outgoing":
            self.ew.wait_and_tap_element(self.OUTGOING_WALLET, 5)
        elif type_of_wallet == "transfer_incoming":
            self.ew.wait_and_tap_element(self.INCOMING_WALLET, 5)

        self.ew.wait_till_element_is_visible(self.WALLET_PICKER, 5)
        wallets_in_picker = self.get_wallets_in_picker()

        if wallet == "random":
            wallet = random.choice(wallets_in_picker)
            if PLATFORM == "Android":
                self.ew.tap_element(wallet)
            else:
                self.ew.tap_element(f'label == "{wallet}"')
        elif wallet == "different":
            wallets_in_picker.remove(selected_wallet)
            wallet = random.choice(wallets_in_picker)
            if PLATFORM == "Android":
                self.ew.tap_element(wallet)
            else:
                self.ew.tap_element(f'label == "{wallet}"')
        elif wallet == "oos":

            for i in wallets_in_picker:
                if i.startswith('Out of Spendee'):
                    postfix_oos = i.split('-')[1]

            wallet = f"Out of Spendee-{postfix_oos}"
            if PLATFORM == "Android":
                self.ew.tap_element(wallet)
            else:
                self.ew.tap_element(f'label == "{wallet}"')
        elif wallet == "not_oos":
            if self.ew.is_element_present("Out of Spendee-false"):
                wallets_in_picker.remove("Out of Spendee-false")
            elif self.ew.is_element_present("Out of Spendee-true"):
                wallets_in_picker.remove("Out of Spendee-true")
            wallet = random.choice(wallets_in_picker)
            if PLATFORM == "Android":
                self.ew.tap_element(wallet)
            else:
                self.ew.tap_element(f'label == "{wallet}"')
        else:
            if PLATFORM == "Android":
                self.ew.tap_element(wallet)
            else:
                self.ew.tap_element(f'label == "{wallet}"')

        self.ew.wait_till_element_is_not_visible(self.WALLET_PICKER, 5)
        if self.ew.is_element_present(self.CONFIRM_BUTTON):
            self.set_exchange_rate()

        v_input = wallet.split('-')[0]
        vr.validate_input_against_output(v_input,
                                         self.get_wallet(type_of_wallet))

    def get_wallet(self, type_of_wallet):
        """ Gets wallet name from requested wallet picker
        :param type_of_wallet: str
        :return: str
        """

        if PLATFORM == "Android":
            if type_of_wallet == "transaction":
                self.ew.wait_till_element_is_visible(
                    self.SELECTED_WALLET_ANDROID, 5)
                return self.ew.get_text_of_element(
                    self.SELECTED_WALLET_ANDROID)
            elif type_of_wallet == "transfer_outgoing":
                self.ew.wait_till_element_is_visible(
                    self.SELECTED_OUTGOING_WALLET_ANDROID, 5)
                return self.ew.get_text_of_element(
                    self.SELECTED_OUTGOING_WALLET_ANDROID)
            elif type_of_wallet == "transfer_incoming":
                self.ew.wait_till_element_is_visible(
                    self.SELECTED_INCOMING_WALLET_ANDROID, 5)
                return self.ew.get_text_of_element(
                    self.SELECTED_INCOMING_WALLET_ANDROID)
        else:
            if type_of_wallet == "transaction":
                self.ew.wait_till_element_is_visible(self.WALLET, 5)
                return self.ew.get_attribute(self.WALLET, "name")
            elif type_of_wallet == "transfer_outgoing":
                self.ew.wait_till_element_is_visible(self.OUTGOING_WALLET, 5)
                return self.ew.get_attribute(self.OUTGOING_WALLET, "name")
            elif type_of_wallet == "transfer_incoming":
                self.ew.wait_till_element_is_visible(self.INCOMING_WALLET, 5)
                return self.ew.get_attribute(self.INCOMING_WALLET, "name")

    def get_wallets_in_picker(self):
        """ Gets wallets names visible inside picker
        :return: list of str
        """
        if PLATFORM == "Android":
            return self.ew.get_attributes(self.WALLET_ITEM, "content-desc")
        else:
            return self.ew.get_attributes(self.WALLET_ITEM, "label")

    def set_start_date(self, start_date):
        """ Sets start date
        :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 == "past":
            start_date = str(datetime.date.today() -
                             datetime.timedelta(days=random.randint(1, 30)))
        elif start_date == "future":
            start_date = str(datetime.date.today() +
                             datetime.timedelta(days=random.randint(1, 30)))
        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.set_calendar_month_year(start_date)
        self.set_calendar_day(start_date)

        vr.validate_input_against_output(start_date, self.get_date("start"))

    def set_calendar_month_year(self, date):
        """ Swipes to requested month and year inside date picker
        :param date: str
        """
        year, month, day = (int(x) for x in date.split('-'))
        if PLATFORM == "Android":
            month_in_app = vs.calendar_months[self.ew.get_text_of_element(
                self.ACTUAL_MONTH_YEAR).split(" ")[0]]
            year_in_app = int(
                self.ew.get_text_of_element(
                    self.ACTUAL_MONTH_YEAR).split(" ")[1])
        else:
            month_in_app = vs.calendar_months[self.ew.get_attribute(
                self.ACTUAL_MONTH_YEAR, "label").split(" ")[0]]
            year_in_app = int(
                self.ew.get_attribute(self.ACTUAL_MONTH_YEAR,
                                      "label").split(" ")[1])

        direction = None
        if (year > year_in_app) or (year == year_in_app
                                    and month > month_in_app):
            direction = "up"
        elif (year < year_in_app) or (year == year_in_app
                                      and month < month_in_app):
            direction = "down"

        iterations = abs((year - year_in_app) * 12 + (month - month_in_app))
        res = self.rs.get_resolution()

        if PLATFORM == "Android":
            if direction == "up":
                for i in range(iterations):
                    self.action.long_press(None, self.rs.all_resolutions[f"{res}"]["x"],
                                           self.rs.all_resolutions[f"{res}"]["calendar_picker_up_y_start"]) \
                        .move_to(None, self.rs.all_resolutions[f"{res}"]["x"],
                                 self.rs.all_resolutions[f"{res}"]["calendar_picker_up_y_end"]) \
                        .release().perform()
            elif direction == "down":
                for i in range(iterations):
                    for d in range(2):
                        self.action.long_press(None, self.rs.all_resolutions[f"{res}"]["x"],
                                               self.rs.all_resolutions[f"{res}"]["calendar_picker_down_y_start"]) \
                            .move_to(None, self.rs.all_resolutions[f"{res}"]["x"],
                                     self.rs.all_resolutions[f"{res}"]["calendar_picker_down_y_end"]) \
                            .release().perform()
        elif PLATFORM == "iOS":
            if direction == "up":
                for i in range(iterations):
                    self.driver.execute_script(
                        "mobile: dragFromToForDuration", {
                            "duration":
                            "0.1",
                            "fromX":
                            self.rs.all_resolutions[f"{res}"]["x"],
                            "fromY":
                            self.rs.all_resolutions[f"{res}"]
                            ["calendar_picker_up_y_start"],
                            "toX":
                            self.rs.all_resolutions[f"{res}"]["x"],
                            "toY":
                            self.rs.all_resolutions[f"{res}"]
                            ["calendar_picker_up_y_end"]
                        })
            elif direction == "down":
                for i in range(iterations):
                    self.driver.execute_script(
                        "mobile: dragFromToForDuration", {
                            "duration":
                            "0.1",
                            "fromX":
                            self.rs.all_resolutions[f"{res}"]["x"],
                            "fromY":
                            self.rs.all_resolutions[f"{res}"]
                            ["calendar_picker_down_y_start"],
                            "toX":
                            self.rs.all_resolutions[f"{res}"]["x"],
                            "toY":
                            self.rs.all_resolutions[f"{res}"]
                            ["calendar_picker_down_y_end"]
                        })

    def set_calendar_day(self, date):
        """ Selects requested day inside date picker
        :param date: str
        """
        if PLATFORM == "Android":
            year, month, day = (int(x) for x in date.split('-'))
            if date == str(datetime.date.today()):
                self.ew.tap_element(
                    f"today {datetime.date(year, month, day).strftime('%A')} {datetime.date(year, month, day).strftime('%B')} {day} selected You have no entries for this day "
                )
            else:
                self.ew.tap_element(
                    f" {datetime.date(year, month, day).strftime('%A')} {datetime.date(year, month, day).strftime('%B')} {day} "
                )

        elif PLATFORM == "iOS":
            self.ew.wait_and_tap_element(
                f"native.calendar.SELECT_DATE_SLOT-{date}", 10)

    def get_date(self, type_of_date):
        """ Gets selected date
        :param type_of_date: str
        """
        is_transaction = self.ew.is_element_present(
            self.TRANSACTION_HEADER_TITLE)
        if type_of_date == "start":
            date_ios = self.START_DATE
            if is_transaction:
                date_android = self.SELECTED_START_DATE_ANDROID
            else:
                date_android = self.SELECTED_START_DATE_ANDROID_BUDGET
        else:
            date_ios = self.END_DATE
            if is_transaction:
                date_android = self.SELECTED_END_DATE_ANDROID
            else:
                date_android = self.SELECTED_END_DATE_ANDROID_BUDGET
        try:
            if PLATFORM == "Android":
                try:
                    self.ew.wait_till_element_is_visible(date_android, 5)
                except NoSuchElementException:
                    if type_of_date == "start":
                        if is_transaction:
                            date_android = self.SELECTED_START_DATE_ANDROID_2
                        else:
                            date_android = self.SELECTED_START_DATE_ANDROID_BUDGET_2
                    else:
                        if is_transaction:
                            date_android = self.SELECTED_END_DATE_ANDROID_2
                        else:
                            date_android = self.SELECTED_END_DATE_ANDROID_BUDGET_2
                date_in_app = self.ew.get_text_of_element(date_android)
            else:
                self.ew.wait_till_element_is_visible(date_ios, 5)
                date_in_app = self.ew.get_attribute(date_ios, "name")
        except (NoSuchElementException, AttributeError):
            return None

        if date_in_app == "Today" or date_in_app == "Yesterday?":
            date = str(datetime.date.today())
        elif date_in_app == "Yesterday":
            date = str(datetime.date.today() - datetime.timedelta(days=1))
        elif date_in_app == "Tomorrow":
            date = str(datetime.date.today() + datetime.timedelta(days=1))
        elif date_in_app is None or date_in_app == "Never":
            return None
        else:
            try:
                month, day, year = (str(x) for x in date_in_app.split(' '))
                day = day.replace(",", "")
            except ValueError:
                month, day = (str(x) for x in date_in_app.split(' '))
                year = str(datetime.date.today().year)
            month = str(datetime.datetime.strptime(month, "%B").month).zfill(2)
            date = f"{year}-{month}-{day.zfill(2)}"

        return date

    def set_note(self, note):
        """ Insert note into note input
        :param note: str
        """
        if note == "random":
            note = ''.join([
                random.choice(string.ascii_lowercase + string.digits)
                for n in range(0, 8)
            ])
        self.ew.wait_till_element_is_visible(self.NOTE_ELEMENT, 5)
        self.ew.get_element(self.NOTE).send_keys(note)
        if self.driver.is_keyboard_shown():
            self.ew.tap_element(self.NOTE_ELEMENT)

        vr.validate_input_against_output(note, self.get_note())

    def get_note(self):
        """ Gets note from note picker
        :return: str
        """
        try:
            if PLATFORM == "Android":
                note = self.ew.get_text_of_element(self.NOTE)
                if note == "Write a note":
                    note = ""
                return note
            else:
                return self.ew.get_text_of_elements(self.SELECTED_NOTE_IOS)[2]
        except IndexError:
            return None

    def set_label(self, label):
        """ Selects label from visible labels, if there is no requested label, it creates one
        :param label: str
        """
        self.ew.wait_till_element_is_visible(self.LABELS, 5)
        if label == "random":
            if self.ew.is_element_present(self.LABEL_ITEM):
                labels = self.get_labels(False)
                label = random.choice(labels)
                if PLATFORM == "Android":
                    self.ew.tap_element(label)
                    time.sleep(0.5)
                else:
                    i = labels.index(label)
                    self.action.tap(self.ew.get_elements(
                        self.LABEL_ITEM)[i]).perform()
                vr.validate_input_against_more_outputs(label,
                                                       self.get_labels(True))
            else:
                self.create_label(label)
        else:
            if PLATFORM == "Android":
                if self.ew.is_element_present(label):
                    self.ew.tap_element(label)
                    time.sleep(0.5)
                    vr.validate_input_against_more_outputs(
                        label, self.get_labels(True))
                else:
                    self.create_label(label)
            else:
                labels = self.get_labels(False)
                if label in labels:
                    i = labels.index(label)
                    self.action.tap(self.ew.get_elements(
                        self.LABEL_ITEM)[i]).perform()
                    vr.validate_input_against_more_outputs(
                        label, self.get_labels(True))
                else:
                    self.create_label(label)

    def fast_select_labels(self, number):
        """ Selects more labels on transaction detail screen
        :param number: int
        """
        self.ew.wait_till_element_is_visible(self.LABELS, 5)
        if self.ew.is_element_present(self.LABEL_ITEM):
            labels = self.get_labels(False)
            x = 0
            for i in labels:
                x = x + 1
                if x <= number:
                    if PLATFORM == "Android":
                        self.ew.tap_element(i)
                        time.sleep(0.5)
                    else:
                        label = labels.index(i)
                        self.action.tap(
                            self.ew.get_elements(
                                self.LABEL_ITEM)[label]).perform()

    def create_label(self, name):
        """ Creates labels on label picker
        :param name: str
        :return:
        """
        if name == "random":
            name = ''.join([
                random.choice(string.ascii_lowercase + string.digits)
                for n in range(0, 8)
            ])

        self.ew.tap_element(self.LABELS)
        self.ew.wait_and_tap_element(self.LABEL_INPUT, 5)
        self.ew.get_element(self.LABEL_INPUT).send_keys(name)
        self.ew.wait_and_tap_element(self.NON_EXISTING_LABEL, 5)
        self.ew.tap_element(self.BACK_BUTTON)

        vr.validate_input_against_more_outputs(name, self.get_labels(True))

    def get_labels(self, only_selected):
        """ Returns all visible or only selected labels
        :param only_selected: bool
        :return: list of str
        """
        self.ew.wait_till_element_is_visible(self.LABELS, 5)
        if PLATFORM == "Android":
            if only_selected:
                labels = self.ew.get_text_of_elements(
                    self.SELECTED_LABELS_ANDROID)
            else:
                labels = self.ew.get_text_of_elements(
                    self.VISIBLE_LABELS_ANDROID)
        else:
            attributes = self.ew.get_attributes(self.VISIBLE_LABELS_IOS,
                                                "name")
            labels = []
            for i in attributes:
                if only_selected:
                    if i.endswith("false") is False:
                        labels.append(i.split("-")[0])
                else:
                    labels.append(i.split("-")[0])

        return labels

    def set_photo(self):
        """Selects photo"""
        self.ew.wait_and_tap_element(self.PHOTO, 5)
        self.ew.wait_and_tap_element(self.CHOOSE_PHOTO, 5)
        if self.ew.is_element_present(self.ALLOW_PHOTO_ACCESS_ANDROID):
            self.ew.tap_element(self.ALLOW_PHOTO_ACCESS_ANDROID)
        if PLATFORM == "Android":
            self.ew.wait_and_tap_element(self.PHOTO_FOLDER, 5)
        self.ew.wait_and_tap_element(self.PHOTO_ITEM, 5)

        vr.validate_input_against_output(True, self.get_photo())

    def get_photo(self):
        """ Returns true if photo is selected
        :return: bool
        """
        try:
            self.ew.wait_till_element_is_visible(self.PHOTO, 5)
            self.ew.wait_till_element_is_visible(self.SELECTED_PHOTO, 3)
        except:
            NoSuchElementException()
        return self.ew.is_element_present(self.SELECTED_PHOTO)

    def set_recurrence(self, recurrence):
        """ Swipes to and selects requested recurrence
        :param recurrence: string
        """
        if recurrence == "random":
            recurrence = random.choice(vs.recurrences)

        self.ew.wait_and_tap_element(self.RECURRENCE, 5)
        self.ew.wait_till_element_is_visible(self.RECURRENCE_PICKER, 5)

        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
        """
        try:
            self.ew.wait_till_element_is_visible(self.RECURRENCE, 5)
            if PLATFORM == "Android":
                try:
                    recurrence = self.ew.get_text_of_element(
                        self.SELECTED_RECURRENCE_ANDROID).lower()
                except AttributeError:
                    recurrence = self.ew.get_text_of_element(
                        self.SELECTED_RECURRENCE_ANDROID_EDIT).lower()
            else:
                recurrence = self.ew.get_attribute(self.RECURRENCE,
                                                   "name").lower()

            if recurrence != "never" and PLATFORM == "Android":
                recurrences_in_app = [
                    "every day", "every 2 days", "every work day",
                    "every week", "every 2 weeks", "every 4 weeks",
                    "every month", "every 2 months", "every 3 months",
                    "every 6 months", "every year"
                ]
                recurrence = vs.recurrences[recurrences_in_app.index(
                    recurrence)]
            return recurrence
        except (AttributeError, NoSuchElementException):
            return None

    def set_end_date(self, end_date):
        """ Selects end date from date picker
        :param end_date: str
        """
        start_date = self.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.set_calendar_month_year(end_date)
        self.set_calendar_day(end_date)

        vr.validate_input_against_output(end_date, self.get_date("end"))

    def set_reminder(self, reminder):
        """ Swipes to and selects requested reminder
        :param reminder: str
        """
        if reminder == "random":
            reminder = random.choice(vs.reminders)

        self.ew.wait_and_tap_element(self.REMINDER, 5)
        self.ew.wait_till_element_is_visible(self.REMINDER_PICKER, 5)

        res = self.rs.get_resolution()
        if PLATFORM == "Android":
            item_visible = self.ew.is_element_present(reminder)
            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(reminder)
            self.ew.wait_and_tap_element(reminder, 5)
        else:
            item_visible = self.ew.get_attribute(reminder, "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(reminder, "visible")
            self.driver.execute_script("mobile: tap", {
                "x": 100,
                "y": 50,
                "element": self.ew.get_element(reminder)
            })

        vr.validate_input_against_output(reminder, self.get_reminder())

    def get_reminder(self):
        """ Gets selected reminder
        :return: str
        """
        try:
            self.ew.wait_till_element_is_visible(self.REMINDER, 5)
            if PLATFORM == "Android":
                reminder = self.ew.get_text_of_element(
                    self.SELECTED_REMINDER_ANDROID)
            else:
                reminder = self.ew.get_attribute(self.REMINDER, "name")

            if reminder != "Never":
                reminders_in_app = [
                    "On a transaction date", "1 day before", "2 days before",
                    "3 days before", "4 days before", "5 days before",
                    "6 days before", "7 days before"
                ]
                reminder = vs.reminders[reminders_in_app.index(reminder)]
            return reminder
        except (ValueError, NoSuchElementException):
            return None