예제 #1
0
    def __load_po_class(self, path):
        self.table_and_test_file_tabs.table.clear_table()

        if not os.path.exists(path):
            show_dialog_path_doesnt_exist(self, path)
        if not is_correct_python_file(path):
            show_dialog(self, u'File name is incorrect: %s' % path,
                        u'Bad file name')
        else:
            folder = os.path.dirname(path)
            files = [os.path.join(folder, p) for p in os.listdir(folder)
                     if is_correct_python_file(p)]
            self.cb_class_path.Clear()
            self.cb_class_path.AppendItems(files)
            self.cb_class_path.Select(files.index(path))
            try:
                self.__cur_po_class = PageObjectClass.parse_string_to_po_class(read_file(path))
                area = self.__cur_po_class.area
                self.image_panel.set_po_fields(self.__cur_po_class.fields)
                self.image_panel.load_image(self.__cur_po_class.img_path, area)

                self.cb_class_path.SetValue(self.__cur_po_class.file_path)

                self.table_and_test_file_tabs.load_po_class(self.__cur_po_class)
            except Exception:
                self.__cur_po_class = None
                show_error_dialog(self, traceback.format_exc(),
                                  u'Failed to open file %s' % path)
예제 #2
0
    def __find_selectors(self, evt):
        browser = self.main_frame.get_browser()
        if browser:
            url = self.main_frame.get_url()
            if not StringUtils.is_url_correct(url):
                show_dialog(self, u'Bad url: %s' % url, u'Bad url')
            else:
                dialog = DialogWithText(self, 'Finding selectors...')
                handler = WxTextCtrlHandler(dialog.txt_ctrl)
                logger = Logger(log_to_console=False, handler=handler)

                dialog.Show()

                generator = PageObjectGenerator(browser, logger)

                def find_selectors():
                    dialog.btn_ok.Disable()
                    self.po_fields = generator.get_all_po_fields(url, None)
                    logger.info(u'DONE')
                    self.__update_table()
                    dialog.btn_ok.Enable()

                thread = Thread(target=find_selectors)
                thread.setDaemon(True)
                thread.start()
예제 #3
0
    def __open_url(self, evt):
        url = self.__txt_url.GetValue()
        if StringUtils.is_url_correct(url):
            self.bth_open_url.Disable()

            name = self.get_browser_initials()

            try:
                if self.__browser and self.__browser.get_browser_initials(
                ) != name:
                    self.__browser.quit()
                    self.__browser = Browser(name)
                elif not self.__browser:
                    self.__browser = Browser(name)
            except Exception:
                show_error_dialog(self, traceback.format_exc(),
                                  u'Failed to open browser')
                self.__browser = None

            if self.__browser:
                self.__browser.open(url)
            # TODO: if generator or selector -> load image
            self.bth_open_url.Enable()
        else:
            show_dialog(self, u'Bad url: %s' % url, u'Bad url')
예제 #4
0
    def __open_or_create_test_file(self, style):
        if self.__cur_po_class:
            folder = self.GetTopLevelParent().get_root_folder()
            if not folder:
                folder = os.path.dirname(self.__cur_po_class.file_path)
            elif RootFolder.TESTS_FOLDER in os.listdir(folder):
                folder = os.path.join(folder, RootFolder.TESTS_FOLDER)

            dialog = FileDialog(self,
                                defaultDir=folder,
                                style=style,
                                wildcard='*.py')
            if dialog.ShowModal() == ID_OK:
                test_file = dialog.GetPath()
                load_file = style == FD_OPEN

                filename = os.path.basename(test_file)
                if StringUtils.is_test_file_name_correct(test_file):
                    test_file_ui = TestFileUI(self.tabs, test_file,
                                              self.__cur_po_class, load_file)
                    self.tabs.AddPage(test_file_ui, filename)
                    self.tabs.SetSelection(self.tabs.GetPageCount() - 1)

                    if style == FD_SAVE:
                        test_file_ui.set_file_was_changed()
                else:
                    show_dialog_bad_name(self, filename, 'my_first_test.py')
        else:
            show_dialog(self,
                        u'Please select class file.',
                        u'Class file was not opened')
예제 #5
0
    def __open_or_create_test_file(self, style):
        if self.__cur_po_class:
            folder = self.GetTopLevelParent().get_root_folder()
            if not folder:
                folder = os.path.dirname(self.__cur_po_class.file_path)
            elif RootFolder.TESTS_FOLDER in os.listdir(folder):
                folder = os.path.join(folder, RootFolder.TESTS_FOLDER)

            dialog = FileDialog(self,
                                defaultDir=folder,
                                style=style,
                                wildcard='*.py')
            if dialog.ShowModal() == ID_OK:
                test_file = dialog.GetPath()
                load_file = style == FD_OPEN

                filename = os.path.basename(test_file)
                if StringUtils.is_test_file_name_correct(test_file):
                    test_file_ui = TestFileUI(self.tabs, test_file,
                                              self.__cur_po_class, load_file)
                    self.tabs.AddPage(test_file_ui, filename)
                    self.tabs.SetSelection(self.tabs.GetPageCount() - 1)

                    if style == FD_SAVE:
                        test_file_ui.set_file_was_changed()
                else:
                    show_dialog_bad_name(self, filename, 'my_first_test.py')
        else:
            show_dialog(self, u'Please select class file.',
                        u'Class file was not opened')
예제 #6
0
    def __find_selectors(self, evt):
        browser = self.main_frame.get_browser()
        if browser:
            url = self.main_frame.get_url()
            if not StringUtils.is_url_correct(url):
                show_dialog(self, u'Bad url: %s' % url, u'Bad url')
            else:
                dialog = DialogWithText(self, 'Finding selectors...')
                handler = WxTextCtrlHandler(dialog.txt_ctrl)
                logger = Logger(log_to_console=False, handler=handler)

                dialog.Show()

                generator = PageObjectGenerator(browser, logger)

                def find_selectors():
                    dialog.btn_ok.Disable()
                    self.po_fields = generator.get_all_po_fields(url, None)
                    logger.info(u'DONE')
                    self.__update_table()
                    dialog.btn_ok.Enable()

                thread = Thread(target=find_selectors)
                thread.setDaemon(True)
                thread.start()
예제 #7
0
 def __on_save_test_file(self, evt):
     count = self.tabs.GetPageCount()
     if count > 1:
         page = self.tabs.GetPage(self.tabs.GetSelection())
         page.save_file()
     else:
         show_dialog(self, u'Please create/open test file.',
                     u'Nothing to save')
예제 #8
0
 def __on_save_test_file(self, evt):
     count = self.tabs.GetPageCount()
     if count > 1:
         page = self.tabs.GetPage(self.tabs.GetSelection())
         page.save_file()
     else:
         show_dialog(self,
                     u'Please create/open test file.',
                     u'Nothing to save')
예제 #9
0
    def generate(self, evt):
        if self.__is_gen_data_correct():
            folder = self.__get_root_folder()
            if RootFolder.PO_FOLDER in os.listdir(folder):
                folder = os.path.join(folder, RootFolder.PO_FOLDER)

            class_name = self.txt_class_name.GetValue()
            file_path = os.path.join(folder,
                                     get_py_file_name_from_class_name(class_name))
            area_as_text = self.txt_selected_area.GetValue()
            url = self.main_frame.get_url()
            if os.path.exists(file_path):
                show_dialog_path_does_exist(self, file_path)
            elif not StringUtils.is_class_name_correct(class_name):
                show_dialog_bad_name(self, class_name, 'Header', 'ContextMenu')
            elif not StringUtils.is_area_correct(area_as_text):
                show_dialog(self, u'Bad selected area: %s' % area_as_text,
                            u'Bad selected area')
            elif not StringUtils.is_url_correct(url):
                show_dialog(self, u'Bad url: %s' % url, u'Bad url')
            else:
                dialog = DialogWithText(self, 'Generating page object class...')
                handler = WxTextCtrlHandler(dialog.txt_ctrl)
                logger = Logger(log_to_console=False, handler=handler)

                dialog.Show()

                area = eval(area_as_text)
                generator = PageObjectGenerator(self.main_frame.get_browser(),
                                                logger)
                folder_path = self.main_frame.get_tmp_dir()

                def generate():
                    dialog.btn_ok.Disable()
                    po_class = generator.get_po_class_for_url(url,
                                                              class_name,
                                                              folder_path,
                                                              area)
                    po_class.save(folder)
                    logger.info(u"Saving class '%s'..." % po_class.name)
                    logger.info(u'Saved file: %s' % po_class.file_path)
                    logger.info(u'Saved file: %s' % po_class.img_path)
                    logger.info(u'DONE')
                    dialog.btn_ok.Enable()

                thread = Thread(target=generate)
                thread.setDaemon(True)
                thread.start()
예제 #10
0
    def generate(self, evt):
        if self.__is_gen_data_correct():
            folder = self.__get_root_folder()
            if RootFolder.PO_FOLDER in os.listdir(folder):
                folder = os.path.join(folder, RootFolder.PO_FOLDER)

            class_name = self.txt_class_name.GetValue()
            file_path = os.path.join(
                folder, get_py_file_name_from_class_name(class_name))
            area_as_text = self.txt_selected_area.GetValue()
            url = self.main_frame.get_url()
            if os.path.exists(file_path):
                show_dialog_path_does_exist(self, file_path)
            elif not StringUtils.is_class_name_correct(class_name):
                show_dialog_bad_name(self, class_name, 'Header', 'ContextMenu')
            elif not StringUtils.is_area_correct(area_as_text):
                show_dialog(self, u'Bad selected area: %s' % area_as_text,
                            u'Bad selected area')
            elif not StringUtils.is_url_correct(url):
                show_dialog(self, u'Bad url: %s' % url, u'Bad url')
            else:
                dialog = DialogWithText(self,
                                        'Generating page object class...')
                handler = WxTextCtrlHandler(dialog.txt_ctrl)
                logger = Logger(log_to_console=False, handler=handler)

                dialog.Show()

                area = eval(area_as_text)
                generator = PageObjectGenerator(self.main_frame.get_browser(),
                                                logger)
                folder_path = self.main_frame.get_tmp_dir()

                def generate():
                    dialog.btn_ok.Disable()
                    po_class = generator.get_po_class_for_url(
                        url, class_name, folder_path, area)
                    po_class.save(folder)
                    logger.info(u"Saving class '%s'..." % po_class.name)
                    logger.info(u'Saved file: %s' % po_class.file_path)
                    logger.info(u'Saved file: %s' % po_class.img_path)
                    logger.info(u'DONE')
                    dialog.btn_ok.Enable()

                thread = Thread(target=generate)
                thread.setDaemon(True)
                thread.start()
예제 #11
0
 def __create_method_or_test(self, evt):
     count = self.tabs.GetPageCount()
     if count > 1:
         page = self.tabs.GetPage(self.tabs.GetSelection())
         if type(page) == PyFileUI:
             self.__create_method(page)
         elif type(page) == TestFileUI:
             self.__create_test(page)
         else:
             show_dialog(
                 self, u'Selected tab is not supported' + LINESEP +
                 u'Please selected test file or page object class',
                 'Bad selected tab')
     else:
         show_dialog(
             self, u'Test file was not created.' + LINESEP +
             'Please create a test file.', u'Test file was not created')
예제 #12
0
 def __create_method_or_test(self, evt):
     count = self.tabs.GetPageCount()
     if count > 1:
         page = self.tabs.GetPage(self.tabs.GetSelection())
         if type(page) == PyFileUI:
             self.__create_method(page)
         elif type(page) == TestFileUI:
             self.__create_test(page)
         else:
             show_dialog(self,
                         u'Selected tab is not supported' +
                         LINESEP +
                         u'Please selected test file or page object class',
                         'Bad selected tab')
     else:
         show_dialog(self,
                     u'Test file was not created.' + LINESEP + 'Please create a test file.',
                     u'Test file was not created')
예제 #13
0
 def __on_menu_click(self, evt):
     if self.__test_file:
         if self.__txt_ctrl_ui.has_one_or_more_methods_or_test_cases():
             item_data = self._get_menu_item_data(evt.GetId())
             method_name = item_data.text
             method = item_data.func
             for pc in self.__parsed_classes:
                 if method in pc.methods.values():
                     arg_spec = pc.get_arg_spec(method)
                     self.__txt_ctrl_ui.append_method_call(
                         self.__field, method_name, method, arg_spec)
                     break
         else:
             show_dialog(self.GetParent(),
                         u'Please create method or test case.',
                         u"Class doesn't have any methods or test cases")
     else:
         show_dialog(self.GetParent(),
                     u'Please select or create test file.',
                     u'Test file was not selected')
예제 #14
0
 def show_content_menu(self, field):
     tabs = self.table_and_test_file_tabs.tabs
     count = tabs.GetPageCount()
     if count > 1:
         selected_tab = tabs.GetPage(tabs.GetSelection())
         if type(selected_tab) in (TestFileUI, PyFileUI):
             file_path = selected_tab.get_file_path()
             txt_ctrl_ui = tabs.GetPage(tabs.GetSelection())
             parsed_classes = self.__get_parsed_classes(field)
             context_menu = FieldContextMenu(field,
                                             parsed_classes,
                                             file_path,
                                             txt_ctrl_ui)
             self.PopupMenu(context_menu)
             context_menu.Destroy()
         else:
             show_dialog(self, u'Please select tab with test file.',
                         u'Tab with test file was not selected')
     else:
         show_dialog(self, u'Please create/open test file.',
                     u'Test file was not created/opened')
예제 #15
0
 def __is_gen_data_correct(self):
     root_folder = self.__get_root_folder()
     class_name = self.txt_class_name.GetValue()
     area = self.txt_selected_area.GetValue()
     if not self.main_frame.get_browser():
         msg = u"Browser is not opened." + LINESEP + "Please open url."
         caption = u'Browser is not opened'
         show_dialog(self, msg, caption)
         return False
     elif not re.match(
             '\(\s*[0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*\)',
             area):
         msg = u"Selected area is not correct: '%s'" % area
         caption = u'Bad selected area'
         show_dialog(self, msg, caption)
         return False
     elif root_folder is None or not os.path.exists(root_folder):
         show_dialog_path_doesnt_exist(self, root_folder)
         return False
     elif len(class_name) == 0:  # if bad class_name
         msg = u"Unsupported name for class: '%s'" % class_name
         caption = u'Bad name for class'
         show_dialog(self, msg, caption)
         return False
     return True
예제 #16
0
 def __on_menu_click(self, evt):
     if self.__test_file:
         if self.__txt_ctrl_ui.has_one_or_more_methods_or_test_cases():
             item_data = self._get_menu_item_data(evt.GetId())
             method_name = item_data.text
             method = item_data.func
             for pc in self.__parsed_classes:
                 if method in pc.methods.values():
                     arg_spec = pc.get_arg_spec(method)
                     self.__txt_ctrl_ui.append_method_call(self.__field,
                                                           method_name,
                                                           method,
                                                           arg_spec)
                     break
         else:
             show_dialog(self.GetParent(),
                         u'Please create method or test case.',
                         u"Class doesn't have any methods or test cases")
     else:
         show_dialog(self.GetParent(),
                     u'Please select or create test file.',
                     u'Test file was not selected')
예제 #17
0
    def __on_btn(self, evt):
        errors = []
        obj = evt.GetEventObject()
        if obj == self.btn_ok:
            self.values = {}
            for txt_ctrl in self.txt_ctrls:
                label_ctrl = self.labels[self.txt_ctrls.index(txt_ctrl)]
                label = label_ctrl.GetLabel()
                value = txt_ctrl.GetValue()
                self.values[label] = value
                if len(value) == 0:
                    errors.append(u"Variable '%s' has empty value '%s'" % (label, value))

            return_code = ID_OK
        else:
            self.values = None
            return_code = ID_CANCEL

        if len(errors) > 0:
            show_dialog(self, LINESEP.join(errors), 'Bad entered data')
        else:
            self.EndModal(return_code)
예제 #18
0
    def __on_btn(self, evt):
        errors = []
        obj = evt.GetEventObject()
        if obj == self.btn_ok:
            self.values = {}
            for txt_ctrl in self.txt_ctrls:
                label_ctrl = self.labels[self.txt_ctrls.index(txt_ctrl)]
                label = label_ctrl.GetLabel()
                value = txt_ctrl.GetValue()
                self.values[label] = value
                if len(value) == 0:
                    errors.append(u"Variable '%s' has empty value '%s'" %
                                  (label, value))

            return_code = ID_OK
        else:
            self.values = None
            return_code = ID_CANCEL

        if len(errors) > 0:
            show_dialog(self, LINESEP.join(errors), 'Bad entered data')
        else:
            self.EndModal(return_code)
예제 #19
0
    def __open_url(self, evt):
        url = self.__txt_url.GetValue()
        if StringUtils.is_url_correct(url):
            self.bth_open_url.Disable()

            name = self.get_browser_initials()

            try:
                if self.__browser and self.__browser.get_browser_initials() != name:
                    self.__browser.quit()
                    self.__browser = Browser(name)
                elif not self.__browser:
                    self.__browser = Browser(name)
            except Exception:
                show_error_dialog(self, traceback.format_exc(), u'Failed to open browser')
                self.__browser = None

            if self.__browser:
                self.__browser.open(url)
            # TODO: if generator or selector -> load image
            self.bth_open_url.Enable()
        else:
            show_dialog(self, u'Bad url: %s' % url, u'Bad url')
예제 #20
0
 def __is_gen_data_correct(self):
     root_folder = self.__get_root_folder()
     class_name = self.txt_class_name.GetValue()
     area = self.txt_selected_area.GetValue()
     if not self.main_frame.get_browser():
         msg = u"Browser is not opened." + LINESEP + "Please open url."
         caption = u'Browser is not opened'
         show_dialog(self, msg, caption)
         return False
     elif not re.match('\(\s*[0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*\)', area):
         msg = u"Selected area is not correct: '%s'" % area
         caption = u'Bad selected area'
         show_dialog(self, msg, caption)
         return False
     elif root_folder is None or not os.path.exists(root_folder):
         show_dialog_path_doesnt_exist(self, root_folder)
         return False
     elif len(class_name) == 0:  # if bad class_name
         msg = u"Unsupported name for class: '%s'" % class_name
         caption = u'Bad name for class'
         show_dialog(self, msg, caption)
         return False
     return True
예제 #21
0
    def append_method_call(self, field, method_name, method, arg_spec):
        is_po_class_file_selected = type(self) == PyFileUI
        # removing arguments with default value
        args = arg_spec.args
        if arg_spec.defaults:
            args = args[:-len(arg_spec.defaults)]

        # removing 'self' argument
        self_txt = 'self'
        if self_txt in args:
            args.remove(self_txt)

        po_class = self.grandparent.get_current_pageobject_class()
        lowered_class_name = po_class.name.lower()

        is_assert_method = method_name.startswith('assert')
        is_browser_method = method_name in ParsedBrowserClass.get_parsed_classes()[0].methods
        is_mouse_method = method_name in ParsedMouseClass.get_parsed_classes()[0].methods
        is_page_object_method = method_name in ParsedPageObjectClass.get_parsed_classes(po_class.file_path)[0].methods

        # replacing 'element' with correctly formatted string - self.obj.field
        element_txt = 'element'
        if element_txt in args:
            element_index = args.index(element_txt)
            if is_po_class_file_selected:
                args[element_index] = u"self.%s" % field.name
            else:
                args[element_index] = u"self.%s.%s" % (lowered_class_name, field.name)

        if is_browser_method:
            caller = 'self.browser'
        elif is_mouse_method:
            caller = 'self.browser.mouse'
        elif is_page_object_method and not is_po_class_file_selected:
            caller = 'self.' + lowered_class_name
        elif is_assert_method:
            caller = None
        else:
            caller = 'self'

        get_prefix = 'get_'
        is_getter_method_and_no_args = method_name.startswith(get_prefix)
        method_kwargs = {}
        if is_getter_method_and_no_args:
            var = method_name.replace(get_prefix, '')
            method_call_template = u"        {var} = {caller}.{method}({method_args})" + LINESEP
            method_kwargs['var'] = var
        elif caller is None:
            method_call_template = u"        {method}({method_args})" + LINESEP
        else:
            method_call_template = u"        {caller}.{method}({method_args})" + LINESEP

        if (len(args) > 1 and (is_browser_method or is_mouse_method) or len(args) > 0 and (
            is_assert_method or is_page_object_method)):
            if is_assert_method or is_page_object_method:
                dialog = MultipleTextEntry(self, 'Please enter values', args)
            else:
                dialog = MultipleTextEntry(self, 'Please enter values', args[1:])
            if dialog.ShowModal() == ID_OK:
                for name, value in dialog.values.items():
                    args[args.index(name)] = value
                method_kwargs.update({'caller': caller,
                                      'method': method_name,
                                      'method_args': u', '.join(args)})
                code_line = method_call_template.format(**method_kwargs)
                code = self.txt_content.GetValue() + LINESEP + code_line
                root_folder = self.GetTopLevelParent().get_root_folder()
                formatted_exception = check_py_code_for_errors(code, root_folder)

                if formatted_exception:
                    show_dialog(self,
                                formatted_exception,
                                u'Values are not Python expressions')
                else:
                    method_kwargs.update({'caller': caller,
                                          'method': method_name,
                                          'method_args': u', '.join(args)})
                    self.append_text(method_call_template.format(**method_kwargs))
        else:
            method_kwargs.update({'caller': caller,
                                  'method': method_name,
                                  'method_args': u', '.join(args)})
            self.append_text(method_call_template.format(**method_kwargs))
예제 #22
0
    def append_method_call(self, field, method_name, method, arg_spec):
        is_po_class_file_selected = type(self) == PyFileUI
        # removing arguments with default value
        args = arg_spec.args
        if arg_spec.defaults:
            args = args[:-len(arg_spec.defaults)]

        # removing 'self' argument
        self_txt = 'self'
        if self_txt in args:
            args.remove(self_txt)

        po_class = self.grandparent.get_current_pageobject_class()
        lowered_class_name = po_class.name.lower()

        is_assert_method = method_name.startswith('assert')
        is_browser_method = method_name in ParsedBrowserClass.get_parsed_classes(
        )[0].methods
        is_mouse_method = method_name in ParsedMouseClass.get_parsed_classes(
        )[0].methods
        is_page_object_method = method_name in ParsedPageObjectClass.get_parsed_classes(
            po_class.file_path)[0].methods

        # replacing 'element' with correctly formatted string - self.obj.field
        element_txt = 'element'
        if element_txt in args:
            element_index = args.index(element_txt)
            if is_po_class_file_selected:
                args[element_index] = u"self.%s" % field.name
            else:
                args[element_index] = u"self.%s.%s" % (lowered_class_name,
                                                       field.name)

        if is_browser_method:
            caller = 'self.browser'
        elif is_mouse_method:
            caller = 'self.browser.mouse'
        elif is_page_object_method and not is_po_class_file_selected:
            caller = 'self.' + lowered_class_name
        elif is_assert_method:
            caller = None
        else:
            caller = 'self'

        get_prefix = 'get_'
        is_getter_method_and_no_args = method_name.startswith(get_prefix)
        method_kwargs = {}
        if is_getter_method_and_no_args:
            var = method_name.replace(get_prefix, '')
            method_call_template = u"        {var} = {caller}.{method}({method_args})" + LINESEP
            method_kwargs['var'] = var
        elif caller is None:
            method_call_template = u"        {method}({method_args})" + LINESEP
        else:
            method_call_template = u"        {caller}.{method}({method_args})" + LINESEP

        if (len(args) > 1 and (is_browser_method or is_mouse_method)
                or len(args) > 0 and
            (is_assert_method or is_page_object_method)):
            if is_assert_method or is_page_object_method:
                dialog = MultipleTextEntry(self, 'Please enter values', args)
            else:
                dialog = MultipleTextEntry(self, 'Please enter values',
                                           args[1:])
            if dialog.ShowModal() == ID_OK:
                for name, value in dialog.values.items():
                    args[args.index(name)] = value
                method_kwargs.update({
                    'caller': caller,
                    'method': method_name,
                    'method_args': u', '.join(args)
                })
                code_line = method_call_template.format(**method_kwargs)
                code = self.txt_content.GetValue() + LINESEP + code_line
                root_folder = self.GetTopLevelParent().get_root_folder()
                formatted_exception = check_py_code_for_errors(
                    code, root_folder)

                if formatted_exception:
                    show_dialog(self, formatted_exception,
                                u'Values are not Python expressions')
                else:
                    method_kwargs.update({
                        'caller': caller,
                        'method': method_name,
                        'method_args': u', '.join(args)
                    })
                    self.append_text(
                        method_call_template.format(**method_kwargs))
        else:
            method_kwargs.update({
                'caller': caller,
                'method': method_name,
                'method_args': u', '.join(args)
            })
            self.append_text(method_call_template.format(**method_kwargs))