Пример #1
0
def get_user_data(test_locale='en'):
    person = {}
    user = Personal(test_locale)
    address = Address(test_locale)

    person['first_name'], person['last_name'] = user.full_name(gender='male').split()
    common.success("Generated user name '%s %s'" % (person['first_name'], person['last_name']))
    person['email'] = user.email(gender='male')
    common.success("Generated email '%s'" % person['email'])
    person['street'] = address.address()
    person['city'] = address.city()
    person['state'] = address.state()
    person['postcode'] = address.postal_code()
    common.success("Generated address '%s %s, %s, %s'" % (person['postcode'], person['state'], person['city'], person['street']))
    person['password'] = ''.join(random.SystemRandom().choice(string.digits + string.ascii_letters) for _ in range(10))
    common.success("Generated password '%s'" % person['password'])
    if (test_locale == 'en'):
        person['country_code'] = 'US'
        person['country'] = 'United States'
        person['state_code'] = 'IA'
        person['state'] = 'Iowa'
    elif (test_locale == 'ru'):
        person['country_code'] = 'RU'
        person['country'] = 'Russian Federation'
        person['state_code'] = None
        person['state'] = None
    else:
        person['country_code'] = None
        person['country'] = None
        person['state_code'] = None
        person['state'] = None
    common.success("Generated country '%s' and state '%s'" % (person['country'], person['state']))
    return person
Пример #2
0
    def machine(self, session, artifact):
        """ Run all modules against an artifact of a given type """
        is_key, value = lookup_key(session, artifact)

        if is_key and value is None:
            error('Unable to find artifact key in session (%s)' % artifact)
            return
        elif is_key and value is not None:
            artifact = value
        else:
            pass

        artifact_type = detect_type(artifact)

        artifact = self.db.find(artifact_type, {'name': artifact}, one=True)

        for key in self.modules.keys():
            if artifact['type'] == key:
                modules = self.modules[artifact['type']]
            elif artifact['subtype'] == key:
                modules = self.modules[artifact['subtype']]

        results = []

        for m in modules:
            result = self.run(m, artifact)

            if m in result['data'].keys():
                if result['data'][m] is not None:
                    if self.db.exists(artifact['type'],
                                      {'name': artifact['name']}):

                        for child in result['children']:
                            child_artifact = create_artifact(
                                child['name'],
                                parent=artifact['name'],
                                _type=child['type'],
                                source=child['source'],
                                subtype=child['subtype'])

                            if not self.db.exists(child['type'],
                                                  {'name': child['name']}):
                                self.db.insert_one(child['type'],
                                                   child_artifact)

                        self.db.update_one(artifact['type'],
                                           {'name': artifact['name']}, result)
                        if len(result['children']) > 0:
                            info('Created child artifacts: %d' %
                                 len(result['children']))

                    results.append({'[%s]' % m: result['data'][m]})

                else:
                    warning('No results found (%s)' % m)

            else:
                warning('Failed to get module results (%s)' % m)

        success('Machine completed')
Пример #3
0
def do_login_admin(browser):
    common.info("Processing login..")
    function_result = True
    # go to the admin login page and wait for page to be loaded
    browser.get("http://localhost/litecart/admin/")
    WebDriverWait(browser, 10).until(
        EC.presence_of_element_located(
            (By.CSS_SELECTOR, "button[value=Login]")))
    # enter credentials
    login_field = browser.find_element_by_name("username")
    login_field.clear()
    login_field.send_keys("admin")
    password_field = browser.find_element_by_name("password")
    password_field.clear()
    password_field.send_keys("admin")
    # press [Login] button and wait for next page to be loaded
    browser.find_element_by_css_selector('button[name="login"]').click()
    WebDriverWait(browser, 10).until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, "li#widget-discussions")))
    if (browser.find_element_by_css_selector("li#widget-discussions")):
        function_result = True
        common.success("Login successful")
    else:
        function_result = False
        common.fail("Cannot login to admin page")
    return function_result
Пример #4
0
 def set_filepath(self, file_path, file_name, create=True):
     if os.path.isdir(file_path):
         self.file_path = os.path.join(file_path, file_name)
         if not os.path.exists(self.file_path):
             self.save()
             success('saved report to %s' % self.file_path)
         return False
     else:
         error('unable to find directory %s - cannot save report' % file_path)
         return False
Пример #5
0
def register_user(browser):
    common.start("Starting registration")
    function_result = True

    browser.get("http://www.localhost/litecart/")
    browser.find_element_by_link_text("New customers click here").click()
    common.success("Get to the registration page")

    user = get_user_data('en')
    # set registration data
    registration_data = [
        {"location": "input[name=firstname]", "value": user["first_name"] },
        {"location": "input[name=lastname]", "value": user["last_name"] },
        {"location": "input[name=address1", "value": user["street"] },
        {"location": "input[name=city]", "value": user["city"] },
        {"location": "#box-create-account input[name=email]", "value": user["email"] },
        {"location": "#box-create-account input[name=password]", "value": user["password"] },
        {"location": "input[name=confirmed_password]", "value": user["password"] },
        {"location": "input[name=postcode]", "value": user["postcode"] }
    ]
    for field in registration_data:
        function_result = input_value_to_input_field(browser, field) and function_result
    # select country and state from dropdown list
    registration_data = [
        {"location": "select[name=country_code]", "value": user["country_code"], "description": user["country"] },
        {"location": "select[name=zone_code]", "value": user["state_code"], "description": user["state"] }
    ]
    for field in registration_data:
        function_result = select_from_dropdown_list(browser, field) and function_result
    # unsubscribe from newsletters
    function_result = set_check_box(browser, "input[name=newsletter]", False) and function_result
    common.info("Uncheck '%s' to unsubscribe from newsletters: ok" % "input[name=newsletter]")
    # click registration button
    browser.find_element_by_css_selector("button[name=create_account]").click()
    common.success("Login successfull")
    # make logout with first appropriate link
    browser.find_element_by_link_text("Logout").click()
    common.success("Logout successfull")
    # make login back using left form
    registration_data = [
        {"location": "#box-account-login input[name=email]", "value": user["email"] },
        {"location": "#box-account-login input[name=password]", "value": user["password"] }
    ]
    for field in registration_data:
        function_result = input_value_to_input_field(browser, field) and function_result
    browser.find_element_by_css_selector("button[name=login]").click()
    common.success("Second login successfull")
    # make logout again to get out of store
    browser.find_element_by_link_text("Logout").click()
    common.success("Logout successfull")

    common.finish(function_result, "Registration")
    return function_result
Пример #6
0
def check_log(browser):
    browser_log_types = browser.log_types
    for type in browser_log_types:
        current_log = browser.get_log(type)
        length = len(current_log)
        if (length):
            common.success("---- There is something in the log '%s'" % type)
            common.info("     records amount: %d" % length)
            for i in range(length):
                common.info("%3d: %s" % (i, current_log[i]))
        else:
            common.success("---- Log '%s' is empty" % type)
    return True
Пример #7
0
    def machine(self, session, artifact):
        """ Run all modules against an artifact of a given type """
        is_key, value = lookup_key(session, artifact)

        if is_key and value is None:
            error('Unable to find artifact key in session (%s)' % artifact)
            return
        elif is_key and value is not None:
            artifact = value
        else:
            pass

        artifact_type = detect_type(artifact)

        artifact = self.db.find(artifact_type, {'name': artifact}, one=True)

        for key in self.modules.keys():
            if artifact['type'] == key:
                modules = self.modules[artifact['type']]
            elif artifact['subtype'] == key:
                modules = self.modules[artifact['subtype']]

        results = []

        for m in modules:
            result = self.run(m, artifact)

            if m in result['data'].keys():
                if result['data'][m] is not None:
                    if self.db.exists(artifact['type'], {'name': artifact['name']}):

                        for child in result['children']:
                            child_artifact = create_artifact(child['name'], parent=artifact['name'],
                                _type=child['type'], source=child['source'], subtype=child['subtype'])

                            if not self.db.exists(child['type'], {'name': child['name']}):
                                self.db.insert_one(child['type'], child_artifact)

                        self.db.update_one(artifact['type'], {'name': artifact['name']}, result)
                        if len(result['children']) > 0:
                            info('Created child artifacts: %d' % len(result['children']))

                    results.append({'[%s]' % m: result['data'][m]})

                else:
                    warning('No results found (%s)' % m)

            else:
                warning('Failed to get module results (%s)' % m)

        success('Machine completed')
Пример #8
0
def browse_catalog(browser):
    common.start("Start browsing catalog")
    function_result = True
    common_litecart.do_login_admin(browser)
    wait10 = WebDriverWait(browser, 10)

    # go to the 'Catalog' page
    browser.get(
        "http://localhost/litecart/admin/?app=catalog&doc=catalog&category_id=1"
    )
    wait10.until(
        EC.presence_of_element_located((By.CSS_SELECTOR, ".data-table")))
    length = len(browser.find_elements_by_css_selector("tbody tr"))

    for i in range(1, length):
        common.info("")
        # go to the 'Catalog' page
        browser.get(
            "http://localhost/litecart/admin/?app=catalog&doc=catalog&category_id=1"
        )
        wait10.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, ".data-table")))
        common.success("Open 'Catalog' page")
        check_log(browser)

        table_lines = browser.find_elements_by_css_selector("tbody tr")
        category = table_lines[i].find_elements_by_css_selector(
            "input")[0].get_property("name")
        if "products" in category:
            product = table_lines[i].find_elements_by_css_selector("a")[0]
            product_name = product.get_property("innerText")
            common.info("Process product '%s'" % product_name)
            product.click()
            wait10.until(
                EC.presence_of_element_located(
                    (By.CSS_SELECTOR, "button[name=delete]")))
            common.success("Process product '%s'" % product_name)
            # Замечание:  если раскомментировать эту строку, то получим замечание в логе драйвера и аварийный останов теста,
            #             но эта строка использовалась для просмотра, что лог доступен и можно вывести его сообщения
            #browser.execute_script("alert('OK');")
            check_log(browser)

    # Done: зайти в админскую часть
    # Done: открыть каталог, категорию, которая содержит товары
    # Done: последовательно открывать страницы товаров
    # Done: проверять, не появляются ли в логе браузера сообщения (любого уровня)
    common.finish(function_result, "Browse catalog")
    return function_result
Пример #9
0
def check_multi_windows(browser):
    # Done: 1) зайти в админку
    # Done: 2) открыть пункт меню Countries (или страницу http://localhost/litecart/admin/?app=countries&doc=countries)
    # Done: 3) открыть на редактирование какую-нибудь страну или начать создание новой
    # Done: 4) возле некоторых полей есть ссылки с иконкой в виде квадратика со стрелкой -- они ведут на внешние страницы и открываются в новом окне, именно это и нужно проверить.
    # Done: требуется именно кликнуть по ссылке, чтобы она открылась в новом окне, потом переключиться в новое окно, закрыть его, вернуться обратно, и повторить эти действия для всех таких ссылок.
    common.start("Checking multiple windows on countries")
    function_result = True
    wait10 = WebDriverWait(browser, 10)

    common_litecart.do_login_admin(browser)
    browser.get("http://localhost/litecart/admin/?app=countries&doc=countries")
    wait10.until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, "button[name=disable]")))
    common.success("Countries page opened")

    browser.find_element_by_link_text("Add New Country").click()
    common.success("New country add page opened")

    # find all links targeting new window and go through them
    for i in range(
            len(browser.find_elements_by_css_selector(".fa-external-link"))):
        common.info("")
        # take another link
        current_element = browser.find_elements_by_css_selector(
            ".fa-external-link")[i]
        # get handles of all windows and current window
        start_handles = set(browser.window_handles)
        start_active_handle = browser.current_window_handle
        # click on the link to open new window
        current_element.click()
        WebDriverWait(browser,
                      30).until(EC.new_window_is_opened(list(start_handles)))
        # get handles of windows and find new one
        next_handles = set(browser.window_handles)
        new_handle = next_handles ^ start_handles
        common.info("New window id = %s" % list(new_handle)[0])
        # switch to the new window
        browser.switch_to_window(list(new_handle)[0])
        common.success("Switched to window '%s'" % list(new_handle)[0])
        common.info("Window title = '%s'" % browser.title)
        # close active (new) window using javascript
        browser.execute_script("close();")
        final_handles = set(browser.window_handles)
        if final_handles == start_handles:
            call_function = common.success
        else:
            common.info("Cannot close window '%s'" % browser.title)
            call_function = common.fail
        call_function("Closed window '%s'" % list(new_handle)[0])
        # switch back to the main window
        browser.switch_to_window(start_active_handle)
        common.success("Switched to main window '%s'" % start_active_handle)

    common.finish(function_result, "Checking multiple windows")
    return function_result
Пример #10
0
def process_shopping_cart(browser):
    common.start("Process shopping")
    function_result = True
    wait10 = WebDriverWait(browser, 10)

    items_to_buy = ["Yellow Duck", "Green Duck", "Purple Duck"]

    for i in range(3):
        browser.get("http://localhost/litecart/en/")
        wait10.until(
            EC.presence_of_element_located((By.LINK_TEXT, "Rubber Ducks")))
        common.success("Open main page")
        browser.find_elements_by_link_text("Rubber Ducks")[0].click()
        common.success("Open 'Rubber Ducks' sales page")
        time.sleep(5)

        product_list = browser.find_elements_by_css_selector(".product")
        for product in product_list:
            item = product.find_element_by_css_selector(".info")
            if (items_to_buy[i] in item.get_property("innerText")):
                common.success("Found product '%s'" % items_to_buy[i])
                item.click()
                wait10.until(
                    EC.presence_of_element_located(
                        (By.CSS_SELECTOR, "div#view-full-page a")))
                full_page_link_object = browser.find_elements_by_css_selector(
                    "div#view-full-page a")
                if (len(full_page_link_object)):
                    common.info(
                        "Popup window with desciption opened, looking for full page.."
                    )
                    full_page_link_object[0].click()
                common.success("Product '%s' page opened" % items_to_buy[i])

                common.info("Set parameters of the product to buy..")
                if (browser.find_elements_by_css_selector(
                        "select[name='options[Size]']")):
                    common_litecart.select_from_dropdown_list(
                        browser, {
                            "location": "select[name='options[Size]']",
                            "value": "Small",
                            "description": "Small"
                        })
                common_litecart.input_value_to_scrollable_field(
                    browser, {
                        "location": "input[name='quantity']",
                        "value": "1"
                    })

                # save the text for the shopping cart dut to it contains price before product adding
                previous_amount = browser.find_element_by_css_selector(
                    ".quantity").get_property("innerText")
                previous_summ = browser.find_element_by_css_selector(
                    ".formatted_value").get_property("innerText")
                common.info(
                    "Shopping cart before operation contains %d products with summ = '%s'"
                    % (int(previous_amount), previous_summ))
                browser.find_element_by_css_selector(
                    "button[name='add_cart_product']").click()
                # wait for the summ for shopping cart to be changed, i.e. previous text to disappear
                wait10.until_not(
                    EC.text_to_be_present_in_element(
                        (By.CSS_SELECTOR, ".quantity"), previous_amount))

                # check the data of the shopping cart
                operation_amount = browser.find_element_by_css_selector(
                    ".quantity").get_property("innerText")
                operation_summ = browser.find_element_by_css_selector(
                    ".formatted_value").get_property("innerText")
                common.info(
                    "Shopping cart after adding contains %d products with summ = '%s'"
                    % (int(operation_amount), operation_summ))
                if (int(operation_amount) - 1) == int(previous_amount):
                    common.success("Product '%s' added to the Shopping Cart" %
                                   items_to_buy[i])
                else:
                    common.fail("Product '%s' added to the Shopping Cart" %
                                items_to_buy[i])
                    function_result = False
                break  # break from loop [for product in product_list]

    # process Shopping Cart
    browser.find_element_by_css_selector("div#cart a").click()
    wait10.until(
        EC.presence_of_element_located((By.CSS_SELECTOR, ".table-bordered")))
    common.success("Open Shopping Cart checkout page")

    items_to_remove = browser.find_elements_by_css_selector(".item")
    while (len(items_to_remove) > 1):
        # save total payment summ to watch for its change
        previous_payment_due = str.split(
            browser.find_element_by_css_selector(
                ".table-bordered .footer").get_property("innerText"))[2]
        # get the name of the product to delete from shopping cart
        item_name = items_to_remove[1].find_element_by_css_selector(
            "strong").get_property("innerText")
        common.info("Delete product '%s' from Shopping Cart.." % item_name)
        common.info("Payment summ before deleting of the product '%s' is: %s" %
                    (item_name, previous_payment_due))
        remove_button = items_to_remove[1].find_element_by_css_selector(
            "button[name=remove_cart_item]")
        remove_button.click()
        wait10.until_not(
            EC.text_to_be_present_in_element(
                (By.CSS_SELECTOR, ".table-bordered .footer"),
                previous_payment_due))
        if (len(
                browser.find_elements_by_css_selector(
                    ".table-bordered .footer"))):
            final_payment_due = str.split(
                browser.find_element_by_css_selector(
                    ".table-bordered .footer").get_property("innerText"))[2]
        else:
            final_payment_due = '$00.00 (There are no items in the cart)'
        common.info("Payment summ after deleting of the product '%s' is: %s" %
                    (item_name, final_payment_due))
        common.success("Delete product '%s' from Shopping Cart" % item_name)
        items_to_remove = browser.find_elements_by_css_selector(".item")

    # Done: открыть главную страницу
    # Done: открыть первый товар из списка (Замечание: сделал по другому, ищу товар с заданным именем, а не какой попался первым)
    # Done: добавить первый товар в корзину (при этом может случайно добавиться товар, который там уже есть, ничего страшного)
    # Done: подождать, пока счётчик товаров в корзине обновится (Замечание: отслеживаю сумму для корзины, а не счётчик товаров)
    # Done: вернуться на главную страницу, повторить предыдущие шаги ещё два раза, чтобы в общей сложности в корзине было 3 единицы товара
    # Done: открыть корзину (в правом верхнем углу кликнуть по ссылке Checkout)
    # Done: удалить все товары из корзины один за другим, после каждого удаления подождать, пока внизу обновится таблица

    common.finish(function_result, "Processing to buy")
    return function_result
Пример #11
0
def add_new_goods(browser):
    common.start("Start add new goods")
    function_result = True
    common_litecart.do_login_admin(browser)

    wait = WebDriverWait(browser, 10)
    # go to the 'Add New Product' page
    browser.find_element_by_link_text("Catalog").click()
    wait.until(
        EC.presence_of_element_located((By.CSS_SELECTOR, "ul.pull-right")))
    common.success("Open 'Add New Product' page")
    browser.find_elements_by_css_selector("ul.pull-right a")[1].click()
    common.success("Open 'General' tab")

    # fill the data on the 'General' tab
    # Status
    browser.execute_script(
        "arguments[0].click();",
        browser.find_element_by_css_selector("input[name=status][value='1']"))
    #browser.execute_script("document.querySelector(\"input[name=status][value='1']\").click()")
    common.info("Set %s = '%s': ok" % ("input[name=status]", "Enabled"))
    # Categories
    common_litecart.set_checkbox(browser,
                                 "input[name='categories[]'][value='0']", True)
    common_litecart.set_checkbox(browser,
                                 "input[name='categories[]'][value='1']", True)
    # Default category -- skipped
    # Product Groups
    common_litecart.set_checkbox(
        browser, "input[name='product_groups[]'][value='1-1']", False)
    common_litecart.set_checkbox(
        browser, "input[name='product_groups[]'][value='1-2']", False)
    common_litecart.set_checkbox(
        browser, "input[name='product_groups[]'][value='1-3']", True)
    # Date Valid From
    browser.find_element_by_css_selector(
        "input[name=date_valid_from]").send_keys("01.05.2017")
    common.info("Set %s = '%s': ok" %
                ("input[name=date_valid_from]", "01.05.2017"))
    # Date Valid To
    browser.find_element_by_css_selector(
        "input[name=date_valid_to]").send_keys("01.09.2017")
    common.info("Set %s = '%s': ok" %
                ("input[name=date_valid_to]", "01.09.2017"))

    # Code
    common_litecart.input_value_to_input_field(browser, {
        "location": "input[name=code]",
        "value": "fd001"
    })
    # Name
    common_litecart.input_value_to_input_field(browser, {
        "location": "input[name='name[en]']",
        "value": "Fried Duck"
    })
    # SKU
    common_litecart.input_value_to_input_field(browser, {
        "location": "input[name=sku]",
        "value": "FD001"
    })
    # GTIN -- skipped
    # TARIC -- skipped
    # Quantity
    common_litecart.input_value_to_input_field(browser, {
        "location": "input[name=quantity]",
        "value": 70
    })
    common_litecart.select_from_dropdown_list(
        browser, {
            "location": "select[name=quantity_unit_id]",
            "value": "1",
            "description": "pcs"
        })
    # Weight
    common_litecart.input_value_to_scrollable_field(browser, {
        "location": "input[name=weight]",
        "value": "4.5"
    })
    common_litecart.select_from_dropdown_list(
        browser, {
            "location": "select[name=weight_class]",
            "value": "lb",
            "description": "lb"
        })
    # Width x Height x Length
    common_litecart.input_value_to_scrollable_field(browser, {
        "location": "input[name=dim_x]",
        "value": "20,0"
    })
    common_litecart.input_value_to_scrollable_field(browser, {
        "location": "input[name=dim_y]",
        "value": "30,0"
    })
    common_litecart.input_value_to_scrollable_field(browser, {
        "location": "input[name=dim_z]",
        "value": "40,0"
    })
    common_litecart.select_from_dropdown_list(browser, {
        "location": "select[name=dim_class]",
        "value": "cm",
        "description": "cm"
    })
    # Delivery Status
    common_litecart.select_from_dropdown_list(
        browser, {
            "location": "select[name=delivery_status_id]",
            "value": "1",
            "description": "3-5 days"
        })
    # Sold Out Status
    common_litecart.select_from_dropdown_list(
        browser, {
            "location": "select[name=sold_out_status_id]",
            "value": "1",
            "description": "Sold out"
        })
    # Images
    common_litecart.input_value_to_input_field(
        browser, {
            "location": "input[name='new_images[]']",
            "value": os.getcwd() + "\\images\\fried_duck.jpg"
        })
    common.info("Set %s = '%s': ok" %
                ("input[name='new_images[]']",
                 os.getcwd() + "\\images\\fried_duck.jpg"))

    # go to the 'Information' tab
    browser.find_element_by_css_selector("a[href='#tab-information']").click()
    wait.until(
        EC.presence_of_element_located(
            (By.CSS_SELECTOR, "input[name='meta_description[en]']")))
    common.success("Open 'Information' tab")
    # fill the data on the 'Information' tab
    # Manufacturer
    common_litecart.select_from_dropdown_list(
        browser, {
            "location": "select[name=manufacturer_id]",
            "value": "1",
            "description": "ACME Corp."
        })
    # Supplier -- skipped
    # Keywords
    common_litecart.input_value_to_input_field(browser, {
        "location": "input[name=keywords]",
        "value": "fried duck food"
    })
    # Short Description
    common_litecart.input_value_to_input_field(
        browser, {
            "location": "input[name='short_description[en]']",
            "value": "short description"
        })
    # Description
    common_litecart.input_value_to_input_field(
        browser, {
            "location": "textarea[name='description[en]']",
            "value": "Full description of the fried duck"
        })
    # Attributes -- skipped
    # Head Title -- skipped
    # Meta Description -- skipped

    # go to the 'Prices' tab
    browser.find_element_by_css_selector("a[href='#tab-prices']").click()
    wait.until(
        EC.presence_of_element_located(
            (By.CSS_SELECTOR, "input[name='gross_prices[EUR]']")))
    common.success("Open 'Prices' tab")
    # fill the data on the 'Prices' tab
    # Purchase Price
    common_litecart.input_value_to_scrollable_field(browser, {
        "location": "input[name=purchase_price]",
        "value": "25"
    })
    common_litecart.select_from_dropdown_list(
        browser, {
            "location": "select[name=purchase_price_currency_code]",
            "value": "USD",
            "description": "US Dollars"
        })
    # Tax Class -- skipped
    # Price
    common_litecart.input_value_to_input_field(browser, {
        "location": "input[name='prices[USD]']",
        "value": "25"
    })
    # Price Incl. Tax -- skipped

    # press 'SAVE' button
    browser.find_element_by_css_selector("button[name=save]").click()

    # go to the main store page, tab 'NEW' and check if new goods are there
    browser.get("http://localhost/litecart/")
    browser.find_element_by_css_selector("a[href='#latest-products']").click()
    if (browser.find_elements_by_css_selector("a[title='Fried Duck']")):
        common.success("Found new item in the store")

    common.finish(function_result, "Add new goods")
    return function_result