示例#1
0
    def __init__(self, config, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'tag_manage_widget.ui')
        uic.loadUi(ui_file_path, self)

        self.db_helper = DBCommandLineHelper()
        self.message_box = QMessageBox()

        self.tag_names_line_edit = TagNamesLineEdit()
        self.tag_names_line_edit.setPlaceholderText("Tag Names")
        self.cmp = None
        self.set_completer()
        self.selected_tag_names_layout.insertWidget(0, self.tag_names_line_edit)

        add_icon = QIcon()
        add_icon.addPixmap(QPixmap(config.images + '/add.png'), QIcon.Normal, QIcon.Off)
        self.new_tag_btn.setIcon(add_icon)
        self.tag_editor = None
        self.tag_list = None
        self.set_tag_list_widget()   # init data

        self.select_btn.clicked.connect(self.select_event)
        self.cancel_btn.clicked.connect(self.close)
        self.new_tag_btn.clicked.connect(self.new_tag_event)

        self.refresh_signal.connect(self.set_tag_list_widget, Qt.QueuedConnection)
示例#2
0
class CaseDataManager:
    def __init__(self):
        self.db_helper = DBCommandLineHelper()

    def get_case_data_count(self, case_id):
        case_data_list = self.get_run_format_data(case_id)
        return len(case_data_list)

    def get_case_data(self, case_id):
        case_data_list = []
        case = self.db_helper.query_case_by_id(case_id)
        header_relation_list = eval(case.header_relation) if case.header_relation else []
        case_data_list.append(header_relation_list)
        if case.data_relation is not None and case.data_relation:
            data_relation_list = eval(case.data_relation)
            for data_relation in data_relation_list:
                temp_data_list = []
                for data_id in data_relation:
                    case_data = CaseData()
                    if data_id:
                        temp_case_data = self.db_helper.query_case_data(id=int(data_id))
                        case_data.id = temp_case_data.id
                        case_data.data = temp_case_data.data
                        case_data.init_data = temp_case_data.data
                    temp_data_list.append(case_data)
                case_data_list.append(temp_data_list)
        return case_data_list
示例#3
0
def update_task_record_stats():
    '''
    更新event 统计数据
    :return:
    '''
    task_record_statses = DBCommandLineHelper.get_task_record_stats([0])
    if task_record_statses:
        for task_record_stats in task_record_statses:
            total_count = 0
            pass_count = 0
            fail_count = 0
            if task_record_stats.task_records:
                total_count = len(task_record_stats.task_records)
                for task_records in task_record_stats.task_records:
                    if task_records.status == task_records.pass_flag:
                        pass_count += 1
                    else:
                        fail_count += 1
            task_record_stats.total_count = total_count
            task_record_stats.pass_count = pass_count
            task_record_stats.fail_count = fail_count
            task_record_stats.end_time = task_record_stats.task_records[
                len(task_record_stats.task_records) -
                1].end_time if len(task_record_stats.task_records
                                   ) > 0 else task_record_stats.end_time
        DBCommandLineHelper.update_data()
示例#4
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.dBCommandLineHelper = DBCommandLineHelper()
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'add_case.ui')
        uic.loadUi(ui_file_path, self)

        screen = QDesktopWidget().screenGeometry()
        self.resize(screen.width() / 5 * 2, screen.height() / 5 * 2)

        self.search_button = SearchButton()
        self.tag_names_line_edit = TagLineEdit("tag_names_line_edit",
                                               self.search_button)
        self.tag_names_line_edit_adapter()
        self.tag_list = None

        self.result_widget = RunnerTableWidget(
            self.dBCommandLineHelper.query_case_all(), [])
        self.result_table_layout.insertWidget(0, self.result_widget)

        self.message_box = QMessageBox()

        self.search_button.clicked.connect(self.search_event)
        self.selectcasebtn.clicked.connect(self.select_event)
        self.casecancelbtn.clicked.connect(self.close)
示例#5
0
def get_record_by_case_id(case_id):
    '''
    获取详细record
    :param case_id:
    :return:
    '''
    task_record = DBCommandLineHelper.query_record_by_case_id(case_id)
    return task_record
def get_record_by_case_id(case_id):
    '''
    获取详细record
    :param case_id:
    :return:
    '''
    task_record = DBCommandLineHelper.query_record_by_case_id(case_id)
    return task_record
示例#7
0
    def __init__(self, tester, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'case_run.ui')
        uic.loadUi(ui_file_path, self)

        # set icon
        run_icon = QIcon()
        self.tester = tester
        self.config = self.tester.get_config()

        run_icon.addPixmap(QPixmap(self.config.images + '/run.png'),
                           QIcon.Normal, QIcon.Off)
        self.run_stop_btn.setIcon(run_icon)

        add_icon = QIcon()
        add_icon.addPixmap(QPixmap(self.config.images + '/add.png'),
                           QIcon.Normal, QIcon.Off)
        self.addbtn.setIcon(add_icon)

        self.message_box = QMessageBox()

        self.dBCommandLineHelper = DBCommandLineHelper()

        self.addbtn.clicked.connect(self.click_add_case)
        self.run_stop_btn.clicked.connect(self.click_run_stop_btn)

        self.add_case_widget = None
        self.add_device_widget = None

        self.splitter = None
        self.case_widget = RunnerTableWidget([], [0])
        self.log_area = Console()
        self.splitter_setting()

        self.status_listener = CaseRunStatusListener()
        self.status_listener.listener_msg_signal.connect(
            self.update_case_name_color, Qt.QueuedConnection)
        self.tester.add_run_status_listener(self.status_listener)
示例#8
0
    def __init__(self, show_case_editor_signal, tester, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.show_case_editor_signal = show_case_editor_signal
        self.db_helper = DBCommandLineHelper()
        self.case_data_manager = CaseManager()
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'case_manager.ui')
        uic.loadUi(ui_file_path, self)
        self.add_case_button.clicked.connect(self.add_case)  # add case event
        self.tester = tester  # 从上级窗体获得Tester()
        # case 搜索
        self.search_button = SearchButton()
        self.search_button.clicked.connect(self.update_table_data_by_search_line)
        self.tag_names_line_edit = TagLineEdit('tag_names_line_edit', self.search_button)
        self.query_conditions_layout.insertWidget(5, self.tag_names_line_edit)
        self.table_widget = TableWidget(self.show_case_editor_signal, self.tester, [])  # init ui table

        self.delete_case_button.clicked.connect(self.delete_case)
        self.export_button.clicked.connect(self.export_data)
        self.import_button.clicked.connect(self.import_data)
        self.add_tag_button.clicked.connect(self.add_tag)
        self.delete_tag_button.clicked.connect(self.delete_tag)
        self.modify_tag_button.clicked.connect(self.modify_tag)

        self.button_style(self.delete_case_button, '/delete.png', 'Delete')
        self.button_style(self.add_case_button, '/add.png', 'Add')
        self.button_style(self.import_button, '/import.png', 'Import')
        self.button_style(self.export_button, '/export.png', 'Export')
        self.button_style(self.add_tag_button, '/add.png', 'Add')
        self.button_style(self.delete_tag_button, '/delete.png', 'Delete')
        self.button_style(self.modify_tag_button, '/edit.png', 'Modify')

        self.set_tag_list_widget()  # show all tags
        self.set_tag_search_line()  # Set the tag input line automatic completion
        self.data_message_layout.insertWidget(1, self.table_widget)
        self.refresh_signal.connect(self.refresh, Qt.QueuedConnection)
def update_task_record_stats():
    '''
    更新event 统计数据
    :return:
    '''
    task_record_statses = DBCommandLineHelper.get_task_record_stats([0])
    if task_record_statses:
        for task_record_stats in task_record_statses:
            total_count = 0
            pass_count = 0
            fail_count = 0
            if task_record_stats.task_records:
                total_count = len(task_record_stats.task_records)
                for task_records in task_record_stats.task_records:
                    if task_records.status == task_records.pass_flag:
                        pass_count += 1
                    else:
                        fail_count += 1
            task_record_stats.total_count = total_count
            task_record_stats.pass_count = pass_count
            task_record_stats.fail_count = fail_count
            task_record_stats.end_time = task_record_stats.task_records[len(task_record_stats.task_records) - 1].end_time if len(
                task_record_stats.task_records) > 0 else task_record_stats.end_time
        DBCommandLineHelper.update_data()
示例#10
0
 def __init__(self, refresh_signal, tag_name=None, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.refresh_signal = refresh_signal
     self.db_helper = DBCommandLineHelper()
     ui_dir_path = os.path.dirname(__file__)
     ui_file_path = os.path.join(ui_dir_path, 'tag_editor.ui')
     uic.loadUi(ui_file_path, self)
     # set icon
     save_icon = QIcon()
     config = Config()
     save_icon.addPixmap(QPixmap(config.images + '/save.png'), QIcon.Normal, QIcon.Off)
     self.tag_save_btn.setIcon(save_icon)
     self.tag_save_btn.clicked.connect(self.tag_save)
     self.tag_id_line_edit.hide()  # 隐藏line_edit
     self.tag_name_line_edit.setPlaceholderText("Tag Name")  # 设置提示文字
     self.tag_description_text_edit.setPlaceholderText('Tag Description')
     if tag_name:
         self.tag = self.db_helper.query_tag_by_name(tag_name)
         self.tag_id_line_edit.setText(str(self.tag.id))
         self.tag_name_line_edit.setText(self.tag.name)
         self.tag_description_text_edit.setPlainText(self.tag.description)
示例#11
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.dBCommandLineHelper = DBCommandLineHelper()
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'add_case.ui')
        uic.loadUi(ui_file_path, self)

        screen = QDesktopWidget().screenGeometry()
        self.resize(screen.width() / 5 * 2, screen.height() / 5 * 2)

        self.search_button = SearchButton()
        self.tag_names_line_edit = TagLineEdit("tag_names_line_edit", self.search_button)
        self.tag_names_line_edit_adapter()
        self.tag_list = None

        self.result_widget = RunnerTableWidget(self.dBCommandLineHelper.query_case_all(), [])
        self.result_table_layout.insertWidget(0, self.result_widget)

        self.message_box = QMessageBox()

        self.search_button.clicked.connect(self.search_event)
        self.selectcasebtn.clicked.connect(self.select_event)
        self.casecancelbtn.clicked.connect(self.close)
示例#12
0
    def __init__(self, tester, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'case_run.ui')
        uic.loadUi(ui_file_path, self)

        # set icon
        run_icon = QIcon()
        self.tester = tester
        self.config = self.tester.get_config()

        run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off)
        self.run_stop_btn.setIcon(run_icon)

        add_icon = QIcon()
        add_icon.addPixmap(QPixmap(self.config.images + '/add.png'), QIcon.Normal, QIcon.Off)
        self.addbtn.setIcon(add_icon)

        self.message_box = QMessageBox()

        self.dBCommandLineHelper = DBCommandLineHelper()

        self.addbtn.clicked.connect(self.click_add_case)
        self.run_stop_btn.clicked.connect(self.click_run_stop_btn)

        self.add_case_widget = None
        self.add_device_widget = None

        self.splitter = None
        self.case_widget = RunnerTableWidget([], [0])
        self.log_area = Console()
        self.splitter_setting()

        self.status_listener = CaseRunStatusListener()
        self.status_listener.listener_msg_signal.connect(self.update_case_name_color, Qt.QueuedConnection)
        self.tester.add_run_status_listener(self.status_listener)
示例#13
0
class CaseManagerWidget(QWidget):
    refresh_signal = pyqtSignal(name='refresh_data')

    def __init__(self, show_case_editor_signal, tester, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.show_case_editor_signal = show_case_editor_signal
        self.db_helper = DBCommandLineHelper()
        self.case_data_manager = CaseManager()
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'case_manager.ui')
        uic.loadUi(ui_file_path, self)
        self.add_case_button.clicked.connect(self.add_case)  # add case event
        self.tester = tester  # 从上级窗体获得Tester()
        # case 搜索
        self.search_button = SearchButton()
        self.search_button.clicked.connect(self.update_table_data_by_search_line)
        self.tag_names_line_edit = TagLineEdit('tag_names_line_edit', self.search_button)
        self.query_conditions_layout.insertWidget(5, self.tag_names_line_edit)
        self.table_widget = TableWidget(self.show_case_editor_signal, self.tester, [])  # init ui table

        self.delete_case_button.clicked.connect(self.delete_case)
        self.export_button.clicked.connect(self.export_data)
        self.import_button.clicked.connect(self.import_data)
        self.add_tag_button.clicked.connect(self.add_tag)
        self.delete_tag_button.clicked.connect(self.delete_tag)
        self.modify_tag_button.clicked.connect(self.modify_tag)

        self.button_style(self.delete_case_button, '/delete.png', 'Delete')
        self.button_style(self.add_case_button, '/add.png', 'Add')
        self.button_style(self.import_button, '/import.png', 'Import')
        self.button_style(self.export_button, '/export.png', 'Export')
        self.button_style(self.add_tag_button, '/add.png', 'Add')
        self.button_style(self.delete_tag_button, '/delete.png', 'Delete')
        self.button_style(self.modify_tag_button, '/edit.png', 'Modify')

        self.set_tag_list_widget()  # show all tags
        self.set_tag_search_line()  # Set the tag input line automatic completion
        self.data_message_layout.insertWidget(1, self.table_widget)
        self.refresh_signal.connect(self.refresh, Qt.QueuedConnection)

    def refresh(self):
        self.set_tag_search_line()
        self.set_tag_list_widget()

    def add_tag(self):
        '''
        add tag
        :return:
        '''
        self.tag_editor_window = TagEditorWidget(self.refresh_signal)
        self.tag_editor_window.setWindowModality(Qt.ApplicationModal)
        self.tag_editor_window.show()

    def modify_tag(self):
        items = self.tag_list_widget.selectedItems()
        item = items[0]
        if item.text() == '全部' or item.text() == '无标识':
            QMessageBox.warning(self, 'tag select ', 'please select a tag')
        else:
            self.tag_editor_window = TagEditorWidget(self.refresh_signal, item.text())
            self.tag_editor_window.setWindowModality(Qt.ApplicationModal)
            self.tag_editor_window.show()

    def delete_tag(self):
        '''
        delete tag
        :return:
        '''
        items = self.tag_list_widget.selectedItems()
        item = items[0]
        if item.text() == '全部' or item.text() == '无标识':
            QMessageBox.warning(self, 'Tag Select ', 'please select a tag')
        else:
            reply = QMessageBox.information(self, "Tag Delete", "Do you want to delete ["+item.text()+"]",
                                            QMessageBox.Yes | QMessageBox.No)
            if reply == QMessageBox.Yes:  # update case info
                self.db_helper.delete_tag_by_name(item.text())
                self.refresh_signal.emit()

    def import_data(self):
        '''
        import data
        :return:
        '''
        file_name = QFileDialog.getOpenFileName(caption='Open File', directory='/',
                                                filter='dpk files(*.dpk)')
        if file_name[0] and '.dpk' in file_name[0]:
            conflict_tags_message_dict = self.case_data_manager.import_data(file_name[0])
            if conflict_tags_message_dict:
                self.conflict_tags_widget = ConflictTagsWidget(self.refresh_signal, conflict_tags_message_dict,
                                                               self.case_data_manager)
                self.conflict_tags_widget.setWindowModality(Qt.ApplicationModal)
                self.conflict_tags_widget.show()
            else:
                QMessageBox.information(self, ' import operation', 'import success')
                self.refresh_signal.emit()

    def export_data(self):
        '''
        export data
        :return:
        '''
        self.table_widget.get_checked_data()  # todo  尝试能否直接获取到checkboxs 的状态
        if len(self.table_widget.checked_cases_message) > 0:
            path = QFileDialog.getSaveFileName(caption='Save file', directory='/',
                                               filter='dpk file(*.dpk)',
                                               options=QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
            if path[0]:
                case_id_list = []
                for case_message in self.table_widget.checked_cases_message:
                    case_id_list.append(case_message['case_id'])
                self.case_data_manager.export_data(path[0], case_id_list)
                QMessageBox.information(self, 'export operation', 'export success')
        else:
            QMessageBox.warning(self, 'export error', 'please select a case to be exported')

    def button_style(self, button, image_path, text):
        icon = QIcon()
        config = Config()
        icon.addPixmap(QPixmap(config.images + image_path), QIcon.Normal, QIcon.Off)
        button.setIcon(icon)
        button.setText('')
        button.setToolTip(text)
        button.resize(50, 50)
        button.setStyleSheet(
            # 'QPushButton{border-width:0px; background:transparent;} '
            'border:none; '
        )

    def delete_case(self):
        self.table_widget.get_checked_data()  # todo  尝试能否直接获取到checkboxs 的状态
        if len(self.table_widget.checked_cases_message) > 0:
            infor_message = 'Confirm delete article ' + str(len(self.table_widget.checked_cases_message)) + ' case'
            reply = QMessageBox.information(self, 'delete reminder', infor_message, QMessageBox.Yes | QMessageBox.No)
            if reply == QMessageBox.Yes:
                case_ids = []
                for index,case_message in enumerate(self.table_widget.checked_cases_message):
                    self.table_widget.dataTableWidget.removeRow(int(case_message['row_num']) - index)  # 删除行后 行数会变 所以-i
                    case_ids.append(int(case_message['case_id']))
                self.db_helper.batch_delete_case(case_ids)
                del self.table_widget.checked_cases_message[:]  # todo statusbar 应该提示
        else:
            QMessageBox.warning(self, 'delte error', 'please select cases to delete')

    def add_case(self):
        """
        show editor
        :return:
        """
        self.show_case_editor_signal.emit(0, 0)

    def update_table_data_by_list_view(self, tag_name):
        self.table_widget.setParent(None)
        self.data_message_layout.removeWidget(self.table_widget)
        if '全部' == tag_name:
            case_list = self.db_helper.query_case_all()
        elif '无标识' == tag_name:
            case_list = self.db_helper.query_no_tag_case()
        else:
            case_list = self.db_helper.query_case_by_tag_names([tag_name])
        self.table_widget = TableWidget(self.show_case_editor_signal, self.tester, case_list)
        self.data_message_layout.insertWidget(1, self.table_widget)

    def update_table_data_by_search_line(self):
        '''
        update ui table data
        :return:
        '''
        self.table_widget.setParent(None)
        self.data_message_layout.removeWidget(self.table_widget)
        tag_names = self.tag_names_line_edit.text()
        if (tag_names.endswith(';')):
            tag_names = tag_names[0: len(tag_names) - 1]
        case_list = []
        if tag_names != '':
            tag_names = tag_names[:len(tag_names)].split(';')
            case_list = self.db_helper.query_case_by_tag_names(tag_names)
        else:
            case_list = self.db_helper.query_case_all()
        self.table_widget = TableWidget(self.show_case_editor_signal, self.tester, case_list)
        self.data_message_layout.insertWidget(1, self.table_widget)

    def set_tag_list_widget(self):
        '''
        init ui table data and onclick event
        :return:
        '''
        self.tag_list_widget.clear()
        self.tag_list_widget.addItem('全部')
        self.tag_list_widget.addItem('无标识')
        self.tag_list = self.db_helper.query_tag_all()
        for tag in self.tag_list:
            self.tag_list_widget.addItem(tag.name)
        self.tag_list_widget.itemClicked.connect(
            lambda: self.list_widget_item_clicked(self.tag_list_widget.currentItem()))
        item = self.tag_list_widget.item(0)
        item.setSelected(True)
        self.list_widget_item_clicked(item)

    def set_tag_search_line(self):
        '''
        set tag search line
        :return:
        '''
        string_list = []
        tag_names_list = string_list + self.get_tag_names()
        tag_completer = TagCompleter(tag_names_list)
        self.tag_names_line_edit.setCompleter(tag_completer)

    def get_tag_names(self):
        tag_model_list = []
        for tag in self.tag_list:
            tag_model_list.append(tag.name)
        return tag_model_list

    def list_widget_item_clicked(self, tag_list_widget_item):
        self.tag_names_line_edit.is_completer = False
        self.tag_names_line_edit.clear()
        text = tag_list_widget_item.text()
        if tag_list_widget_item.text() == '全部' or tag_list_widget_item.text() == '无标识':
            self.tag_names_line_edit.setText('')
        else:
            text = tag_list_widget_item.text()
            self.tag_names_line_edit.setText(text+';')
        self.update_table_data_by_list_view(text)
        self.tag_names_line_edit.is_completer = True
def get_task_record_stats():
    update_task_record_stats()
    task_record_statses = DBCommandLineHelper.get_task_record_stats()
    return task_record_statses
示例#15
0
 def add_record(self, case_id, device_id, start_time, status, expect):
     DBCommandLineHelper.insert_record(self.task_id, case_id, device_id, start_time,
                                       status,
                                       expect)
示例#16
0
 def __init__(self):
     task_record_stats = DBCommandLineHelper.insert_task_record_stats()
     self.task_id = task_record_stats.id
示例#17
0
 def setUp(self):
     self.db_helper = DBCommandLineHelper()
示例#18
0
class TestDataBase(unittest.TestCase):
    def setUp(self):
        self.db_helper = DBCommandLineHelper()

    def test_operate_tag_data(self):
        ms_str = str(time.time())
        tag_name = "test_tag_name_" + ms_str
        tag_description = "test_tag_name_" + ms_str
        tag = self.db_helper.insert_tag(tag_name, tag_description)  # 插入tag
        dst_tag = self.db_helper.query_tag_by_id(tag.id)  # 根据tag.id 查询tag
        self.assertTrue(tag == dst_tag)
        tag_list = self.db_helper.fuzzy_query_tag_by_name(tag.name)
        self.assertTrue(tag in tag_list)

        dst_tag = self.db_helper.query_tag_by_name(tag.name)
        self.assertTrue(tag == dst_tag)

        tag_list = self.db_helper.query_tag_all()  # 查询所有tag
        self.assertTrue(type(tag_list[0]) is Tag)
        self.db_helper.delete_tag(tag.id)  # 删除tag
        dst_tag = self.db_helper.query_tag_by_id(tag.id)  # 根据tag.id 查询tag、
        self.assertTrue(dst_tag is None)

    def test_operate_case_data(self):
        ms_str = str(time.time())
        tag_name = "test_tag_name_" + ms_str
        tag_description = "test_tag_name_" + ms_str
        tag = self.db_helper.insert_tag(tag_name, tag_description)  # 插入tag
        tags = [tag]
        case_name = case_content = "test_case_name_" + ms_str
        case = self.db_helper.insert_case_with_tags(case_name, case_content, tags)  # 插入case
        dst_case = self.db_helper.query_case_by_id(case.id)
        self.assertTrue(case == dst_case)

        dst_case = self.db_helper.query_case_by_name(True, case.name)
        self.assertTrue(case == dst_case)

        dst_case_list = self.db_helper.query_case_by_name(False, case.name)
        self.assertTrue(case in dst_case_list)

        case_list = self.db_helper.query_case_by_tag_names([tag.name])
        self.assertTrue(type(case_list[0]) is Case)
        # tag_name = "test_tag_name_" + str(time.time())

        # 更改case:
        case = self.db_helper.query_case_by_id(case.id)
        case_id = case.id
        case_name = 'test_case_name_' + str(time.time())
        case.name = case_name
        case.content = 'test_case_name_' + str(time.time())
        tags = self.db_helper.query_tag_all()
        case.tags = tags
        self.db_helper.update_case()
        case = self.db_helper.query_case_by_id(case.id)
        self.assertTrue(case.name == case_name)

        tag_name = "test_tag_name_" + str(time.time())
        case = self.db_helper.insert_case_with_tagnames(case.name, case.content, [tag.name], [tag_name])
        self.assertTrue(type(case) is Case and case.id)

        result = self.db_helper.get_table_data_by_cases_id(str(case.id))
        self.assertTrue(result['case'] and result['tag'] and result['case_tag'])

        self.db_helper.delete_case(case.id)
        dst_case = self.db_helper.query_case_by_id(case.id)
        self.assertTrue(dst_case is None)

    def test_delete_tag_by_name(self):
        tag_name = 'test_123'
        tag = self.db_helper.insert_tag(tag_name, 'test tag')
        case = self.db_helper.insert_case_with_tags('test_123', 'test case', [tag])
        self.db_helper.delete_tag_by_name(tag_name)
        self.assertTrue(self.db_helper.query_case_by_id(case.id) is not None)
        self.assertTrue(self.db_helper.query_tag_by_name(tag_name) is None)
示例#19
0
def get_task_record_stats():
    update_task_record_stats()
    task_record_statses = DBCommandLineHelper.get_task_record_stats()
    return task_record_statses
示例#20
0
class RunWidget(QWidget):
    running = False
    device_list_signal = pyqtSignal(list, name="device_list_signal")
    cases = []

    def __init__(self, tester, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'case_run.ui')
        uic.loadUi(ui_file_path, self)

        # set icon
        run_icon = QIcon()
        self.tester = tester
        self.config = self.tester.get_config()

        run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off)
        self.run_stop_btn.setIcon(run_icon)

        add_icon = QIcon()
        add_icon.addPixmap(QPixmap(self.config.images + '/add.png'), QIcon.Normal, QIcon.Off)
        self.addbtn.setIcon(add_icon)

        self.message_box = QMessageBox()

        self.dBCommandLineHelper = DBCommandLineHelper()

        self.addbtn.clicked.connect(self.click_add_case)
        self.run_stop_btn.clicked.connect(self.click_run_stop_btn)

        self.add_case_widget = None
        self.add_device_widget = None

        self.splitter = None
        self.case_widget = RunnerTableWidget([], [0])
        self.log_area = Console()
        self.splitter_setting()

        self.status_listener = CaseRunStatusListener()
        self.status_listener.listener_msg_signal.connect(self.update_case_name_color, Qt.QueuedConnection)
        self.tester.add_run_status_listener(self.status_listener)

    def splitter_setting(self):
        """
        set splitter
        :return:
        """
        if self.splitter:
            self.splitter = None
        self.splitter = QSplitter(Qt.Vertical)
        self.splitter.setHandleWidth(1)
        # add "case_widget" and "log_area" to splitter
        self.splitter.addWidget(self.case_widget)
        self.splitter.addWidget(self.log_area)

        # set the initial scale: 4:1
        self.splitter.setStretchFactor(0, 4)
        self.splitter.setStretchFactor(1, 1)
        self.case_table_layout.addWidget(self.splitter)

    def click_add_case(self):
        """
        click the button to show add case widget
        :return:
        """
        self.add_case_widget = AddCaseWidget()
        self.add_case_widget.select_case_signal.connect(self.show_cases, Qt.QueuedConnection)
        self.add_case_widget.setWindowModality(Qt.ApplicationModal)
        self.add_case_widget.show()

    def click_run_stop_btn(self):
        """
        start or stop to run case
        :return:
        """
        devices = []
        if self.running:
            self.stop_case()
            return
        if not self.cases:  # cases is null
            self.message_box.warning(self, "Message", "Please add cases first.", QMessageBox.Ok)
            return
        try:
            devices = self.tester.devices()
        except Exception as e:
            self.add_log("<font color='red'>" + str(e) + "</font>")
        if not devices:  # There is no device connected
            self.message_box.warning(self, "Message", "Please connect the device to your computer.", QMessageBox.Ok)
            return
        self.add_device_widget = AddDeviceWidget()
        self.add_device_widget.setWindowModality(Qt.ApplicationModal)
        self.add_device_widget.add_log_signal.connect(self.add_log, Qt.QueuedConnection)
        self.add_device_widget.run_case_signal.connect(self.run_case, Qt.QueuedConnection)
        self.device_list_signal.connect(self.add_device_widget.add_radio_to_widget, Qt.QueuedConnection)
        self.add_device_widget.show()
        try:
            self.device_list_signal.emit(devices)
        except Exception as e:
            self.add_log("<font color='red'><pre>" + str(e) + "</pre></font>")

    def add_log(self, log_info):
        """
        add log to log_area
        :return:
        """
        if self.log_area is None:
            return
        self.log_area.append(log_info)

    def update_case_name_color(self, msg, is_passed):
        """
        update case's font color according to the case's result
        pass: green; fail: red
        :param is_passed:
        :param msg:
        :return:
        """
        if msg.status == 601:
            self.add_log("<font color='green'> Start to install agent.</font>")
        elif msg.status == 602:
            self.add_log("<font color='green'> Install agent success.</font>")
        elif msg.status == 603:
            self.add_log("<font color='red'> Install agent Fail." + "\r Error Info:\r<pre>" + msg.message +
                         "</pre></font>")
        elif msg.status == 701:
            self.add_log("<font color='green'> Start agent.</font>")
        elif msg.status == 702:
            self.add_log("<font color='green'> Stop agent.</font>")
        elif msg.status == 703:
            self.add_log("<font color='red'> Agent error." + "\r Error Info:\r<pre>" + msg.message + "</pre></font>")

        for row_index in range(self.case_widget.dataTableWidget.rowCount()):
            case_id_item = self.case_widget.dataTableWidget.item(row_index, 1)  # get case id from dataTableWidget
            if msg.status == 2:  # test end
                if is_passed:
                    self.add_log("<font color='green'> All cases are Passed.</font>")
                self.stop_case()
                break
            if case_id_item.text() != str(msg.case_id):
                continue
            self.case_widget.dataTableWidget.selectRow(row_index)
            if msg.status == 101:  # default: case pass
                self.update_green(row_index)
            elif msg.status == 500:
                self.update_red(row_index)
                self.add_log("<font color='red'> Case Failed, case id: " + str(msg.case_id) + "</font>")
                self.add_log("<pre><font color='red'>" + str(msg.message) + "</font></pre>")

    def run_case(self, devices):
        kw_case_list = []
        if not self.cases:
            return
        for case_id in self.cases:
            kw_case = KWCase()
            case = self.dBCommandLineHelper.query_case_by_id(case_id)
            kw_case.id = case.id
            kw_case.name = case.name
            kw_case.content = case.content
            kw_case.data = case.data
            kw_case_list.append(kw_case)
        # set icon
        stop_icon = QIcon()
        stop_icon.addPixmap(QPixmap(self.config.images + '/stop.png'), QIcon.Normal, QIcon.Off)
        self.run_stop_btn.setIcon(stop_icon)
        self.run_stop_btn.setText("Stop")
        self.running = True
        if not devices:
            return
        try:
            self.tester.select_devices(devices)
            self.tester.run(kw_case_list)
        except Exception as e:
            self.stop_case()
            self.add_log(str(e))

    def stop_case(self):
        run_icon = QIcon()
        run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off)
        self.run_stop_btn.setIcon(run_icon)          # change icon
        self.run_stop_btn.setText("Run")
        self.running = False
        try:
            self.tester.stop()
            self.tester.stop_server()
        except Exception as e:
            self.add_log(str(e))

    def show_cases(self, id_list):
        """
        show cases in RunnerTableWidget according to id list
        :param id_list:
        :return:
        """
        self.case_table_layout.removeWidget(self.splitter)
        case_list = []
        self.cases = id_list
        for case_id in id_list:
            case = self.dBCommandLineHelper.query_case_by_id(case_id)
            case_list.append(case)
        self.case_widget = RunnerTableWidget(case_list, [0])
        self.splitter_setting()  # reload splitter

    def update_green(self, row_index):
        """
        update item text color to green by row number
        :param row_index:
        :return:
        """
        brush_green_color = QBrush(QColor(55, 177, 88))
        for column_index in range(self.case_widget.dataTableWidget.columnCount()):
            item = self.case_widget.dataTableWidget.item(row_index, column_index)
            item.setForeground(brush_green_color)

    def update_red(self, row_index):
        """
        update item text color to red by row number
        :param row_index:
        :return:
        """
        brush_red_color = QBrush(QColor(255, 0, 0))
        for column_index in range(self.case_widget.dataTableWidget.columnCount()):
            item = self.case_widget.dataTableWidget.item(row_index, column_index)
            item.setForeground(brush_red_color)
示例#21
0
class TestDataBase(unittest.TestCase):
    def setUp(self):
        self.db_helper = DBCommandLineHelper()

    def test_operate_tag_data(self):
        ms_str = str(time.time())
        tag_name = "test_tag_name_" + ms_str
        tag_description = "test_tag_name_" + ms_str
        tag = self.db_helper.insert_tag(tag_name, tag_description)  # 插入tag
        dst_tag = self.db_helper.query_tag_by_id(tag.id)  # 根据tag.id 查询tag
        self.assertTrue(tag == dst_tag)
        tag_list = self.db_helper.fuzzy_query_tag_by_name(tag.name)
        self.assertTrue(tag in tag_list)

        dst_tag = self.db_helper.query_tag_by_name(tag.name)
        self.assertTrue(tag == dst_tag)

        tag_list = self.db_helper.query_tag_all()  # 查询所有tag
        self.assertTrue(type(tag_list[0]) is Tag)
        self.db_helper.delete_tag(tag.id)  # 删除tag
        dst_tag = self.db_helper.query_tag_by_id(tag.id)  # 根据tag.id 查询tag、
        self.assertTrue(dst_tag is None)

    def test_operate_case_data(self):
        ms_str = str(time.time())
        tag_name = "test_tag_name_" + ms_str
        tag_description = "test_tag_name_" + ms_str
        tag = self.db_helper.insert_tag(tag_name, tag_description)  # 插入tag
        tags = [tag]
        case_name = case_content = "test_case_name_" + ms_str
        case = self.db_helper.insert_case_with_tags(case_name, case_content,
                                                    tags)  # 插入case
        dst_case = self.db_helper.query_case_by_id(case.id)
        self.assertTrue(case == dst_case)

        dst_case = self.db_helper.query_case_by_name(True, case.name)
        self.assertTrue(case == dst_case)

        dst_case_list = self.db_helper.query_case_by_name(False, case.name)
        self.assertTrue(case in dst_case_list)

        case_list = self.db_helper.query_case_by_tag_names([tag.name])
        self.assertTrue(type(case_list[0]) is Case)
        # tag_name = "test_tag_name_" + str(time.time())

        # 更改case:
        case = self.db_helper.query_case_by_id(case.id)
        case_id = case.id
        case_name = 'test_case_name_' + str(time.time())
        case.name = case_name
        case.content = 'test_case_name_' + str(time.time())
        tags = self.db_helper.query_tag_all()
        case.tags = tags
        self.db_helper.update_case()
        case = self.db_helper.query_case_by_id(case.id)
        self.assertTrue(case.name == case_name)

        tag_name = "test_tag_name_" + str(time.time())
        case = self.db_helper.insert_case_with_tagnames(
            case.name, case.content, [tag.name], [tag_name])
        self.assertTrue(type(case) is Case and case.id)

        result = self.db_helper.get_table_data_by_cases_id(str(case.id))
        self.assertTrue(result['case'] and result['tag']
                        and result['case_tag'])

        self.db_helper.delete_case(case.id)
        dst_case = self.db_helper.query_case_by_id(case.id)
        self.assertTrue(dst_case is None)

    def test_delete_tag_by_name(self):
        tag_name = 'test_123'
        tag = self.db_helper.insert_tag(tag_name, 'test tag')
        case = self.db_helper.insert_case_with_tags('test_123', 'test case',
                                                    [tag])
        self.db_helper.delete_tag_by_name(tag_name)
        self.assertTrue(self.db_helper.query_case_by_id(case.id) is not None)
        self.assertTrue(self.db_helper.query_tag_by_name(tag_name) is None)
示例#22
0
 def __init__(self):
     self.db_helper = DBCommandLineHelper()
示例#23
0
class AddCaseWidget(QWidget):
    select_case_signal = pyqtSignal(list, name="select_case_signal")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.dBCommandLineHelper = DBCommandLineHelper()
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'add_case.ui')
        uic.loadUi(ui_file_path, self)

        screen = QDesktopWidget().screenGeometry()
        self.resize(screen.width() / 5 * 2, screen.height() / 5 * 2)

        self.search_button = SearchButton()
        self.tag_names_line_edit = TagLineEdit("tag_names_line_edit", self.search_button)
        self.tag_names_line_edit_adapter()
        self.tag_list = None

        self.result_widget = RunnerTableWidget(self.dBCommandLineHelper.query_case_all(), [])
        self.result_table_layout.insertWidget(0, self.result_widget)

        self.message_box = QMessageBox()

        self.search_button.clicked.connect(self.search_event)
        self.selectcasebtn.clicked.connect(self.select_event)
        self.casecancelbtn.clicked.connect(self.close)

    def search_event(self):
        """
        search tags by tag name, and show the result in the table widget
        :return:
        """
        self.result_widget.setParent(None)
        self.result_table_layout.removeWidget(self.result_widget)
        tag_names = self.tag_names_line_edit.text().strip()
        # tag_names is None
        if not tag_names:
            case_list = self.dBCommandLineHelper.query_case_all()
            self.result_widget = RunnerTableWidget(case_list, [])
            self.result_table_layout.insertWidget(0, self.result_widget)
            return

        # tag_names is not None
        tag_names = tag_names.split(';')
        for tag_name in tag_names:
            if not tag_name.strip():  # remove null tag
                tag_names.remove(tag_name.strip())
                continue
        case_list = self.dBCommandLineHelper.query_case_by_tag_names([tag_name.strip() for tag_name in tag_names])
        self.result_widget = RunnerTableWidget(case_list, [])
        self.result_table_layout.insertWidget(0, self.result_widget)

    def select_event(self):
        """
        handle the select event
        :return:
        """
        self.result_widget.get_checked_data()
        if not self.result_widget.checked_cases_message:
            self.message_box.warning(self, "Message", "Please choose cases first.", QMessageBox.Ok)
            return
        id_list = []
        for item in self.result_widget.checked_cases_message:
            id_list.append(int(item["case_id"]))
        self.select_case_signal.emit(id_list)
        self.close()     # close AddCase

    def tag_names_line_edit_adapter(self):
        """
        settings for tag_names_line_edit
        such as completer, placeholder text
        :return:
        """
        self.tag_names_line_edit.setPlaceholderText("Tag names")
        self.search_layout.insertWidget(0, self.tag_names_line_edit)

        self.tag_list = self.dBCommandLineHelper.query_tag_all()  # get all tags
        tag_name_list = []
        for tag in self.tag_list:
            tag_name_list.append(tag.name)
        cmp = TagCompleter(tag_name_list)
        self.tag_names_line_edit.setCompleter(cmp)
示例#24
0
class EditorWidget(QWidget):
    device_and_data_signal = pyqtSignal(list, int, name="device_list_signal")
    import_list_signal = pyqtSignal(set, name="import_list_signal")
    close_cancel_signal = pyqtSignal(name="close_cancel_signal")

    def __init__(self, refresh_signal, tester, case_id=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'case_editor.ui')
        uic.loadUi(ui_file_path, self)

        self.dBCommandLineHelper = DBCommandLineHelper()
        self.tester = tester
        self.config = self.tester.get_config()
        self.debug_runner = self.tester.get_debug_runner()
        self.case_id = case_id
        self.refresh_signal = refresh_signal

        self.init_ui()

        self.is_log_show = True
        self.is_running = False
        self.tag_list = []
        self.parsed_line_list = []
        self.case = None
        self.high_lighter = None
        self.tag_manage_widget = None
        self.add_device_widget = None

        self.message_box = QMessageBox()
        self.add_tag_button = SearchButton()
        self.tag_names_line_edit = TagLineEdit("tag_names_line_edit", self.add_tag_button)
        self.set_tag_name_completer()

        self.splitter = QSplitter(Qt.Vertical)

        self.splitter.setHandleWidth(1)  # set handle width
        self.editor_text_edit = TextEdit(self.debug_runner.core)  # case content TextEdit
        self.console = Console()

        # Add the 'editor text edit' and 'console' to splitter
        self.splitter.addWidget(self.editor_text_edit)
        self.splitter.addWidget(self.console)

        # Set the initial scale: 4:1
        self.splitter.setStretchFactor(0, 4)
        self.splitter.setStretchFactor(1, 1)

        self.editor_layout.addWidget(self.splitter)

        self.import_list_signal.connect(self.editor_text_edit.get_import_from_content, Qt.QueuedConnection)
        self.editor_text_edit.parse_error_info_signal.connect(self.add_info_console, Qt.QueuedConnection)

        self.editor_adapter()  # set completer and highlighter
        self.set_case_edit_data()  # update case

        # run status listener
        self.status_listener = EditorRunStatusListener()
        self.status_listener.editor_listener_msg_signal.connect(self.result_handle, Qt.QueuedConnection)
        self.debug_runner.listener = self.status_listener

        self.data_line = None

        # button event
        self.save_btn.clicked.connect(self.save_case)
        self.run_btn.clicked.connect(self.run_btn_event)
        self.console_btn.clicked.connect(self.log_show_hide_event)
        self.edit_data_btn.clicked.connect(self.add_case_data)
        self.add_tag_button.clicked.connect(self.choose_event)
        # case data
        self.case_manager = CaseManager()
        self.case_data_manage = CaseDataManager()
        self.case_data_count = 0  # init case data count
        self.is_case_data_modify = False

    def init_ui(self):
        """
        init ui, include: resize window
        :return:
        """
        screen = QDesktopWidget().screenGeometry()
        self.resize(screen.width() / 2, screen.height() / 2)
        self.init_btn_icon()

        self.id_line_edit.hide()  # hide line_edit
        self.case_name_line_edit.setPlaceholderText("Case Name")

    def init_btn_icon(self):
        """
        init button icon, including: save button、run button、show/hide console button
        :return:
        """
        save_icon = QIcon()
        save_icon.addPixmap(QPixmap(self.config.images + '/save.png'), QIcon.Normal, QIcon.Off)  # save icon
        self.save_btn.setIcon(save_icon)

        run_icon = QIcon()
        run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off)  # run icon
        self.run_btn.setIcon(run_icon)

        console_icon = QIcon()
        console_icon.addPixmap(QPixmap(self.config.images + '/console.png'), QIcon.Normal, QIcon.Off)  # console icon
        self.console_btn.setIcon(console_icon)

        edit_data_icon = QIcon()
        edit_data_icon.addPixmap(QPixmap(self.config.images + '/edit.png'), QIcon.Normal, QIcon.Off)  # console icon
        self.edit_data_btn.setIcon(edit_data_icon)

    def add_case_data(self):
        """
        show case data widget
        :return:
        """
        if hasattr(self, 'case_data_widget'):
            self.case_data_widget.close()
        self.case_data_widget = CaseDataWidget(self.case_id)
        self.case_data_widget.show()

    def choose_event(self):
        """
        choose tag event, show tags
        :return:
        """
        self.tag_manage_widget = TagManageWidget(self.config)
        self.tag_manage_widget.selected_tag_names_signal.connect(self.set_selected_tag_names)
        self.tag_manage_widget.setWindowModality(Qt.ApplicationModal)
        self.tag_manage_widget.show()

    def set_selected_tag_names(self, tag_names):
        """
        set tag names
        :param tag_names:
        :return:
        """
        original_tag_names = self.tag_names_line_edit.text().strip()
        tag_name_set = set(original_tag_names.split(";"))  # original tag name set
        if not tag_names:
            return
        # handle the repeat tag names
        tag_name_list = tag_names.split(";")
        for tag_name in tag_name_list:
            if (tag_name.strip() in original_tag_names) or (not tag_name.strip()):
                continue
            tag_name_set.add(tag_name.strip())  # add new selected tag name
        all_tag_names = ""
        for tag_name in tag_name_set:
            if not tag_name.strip():
                continue
            all_tag_names += tag_name.strip() + ";"

        self.tag_names_line_edit.is_completer = False
        self.tag_names_line_edit.setText(all_tag_names)
        self.tag_names_line_edit.is_completer = True

    def log_show_hide_event(self):
        if self.is_log_show:
            self.console_btn.setText("Show Console")
            self.console.hide()
            self.is_log_show = False
        else:
            self.console_btn.setText("Hide Console")
            self.console.show()
            self.is_log_show = True

    def add_info_console(self, info):
        """
        append error massage to console
        :param info:
        :return:
        """
        self.console.append(info)

    def result_handle(self, msg, is_passed):
        """
        show the debug result in console
        :param is_passed:
        :param msg:
        :return:
        """

        if msg.status == 601:
            self.add_info_console("<font color='green'> Start to install agent.</font>")
        elif msg.status == 602:
            self.add_info_console("<font color='green'> Install agent success.</font>")
        elif msg.status == 603:
            self.add_info_console("<font color='red'> Install agent Fail." + "\r Error Info:\r<pre>" + msg.message +
                                  "</pre></font>")
        elif msg.status == 701:
            self.add_info_console("<font color='green'> Start agent.</font>")
        elif msg.status == 702:
            self.add_info_console("<font color='green'> Stop agent.</font>")
        elif msg.status == 703:
            self.add_info_console("<font color='red'> Agent error." + "\r Error Info:\r<pre>" + msg.message +
                                  "</pre></font>")
        if msg.status == 500:  # fail
            self.add_info_console("<font color='red'> <pre>" + str(msg.message) + "</pre></font>")
        if msg.status == 102 and is_passed:
            self.add_info_console("<font color='green'> The case is Passed.</font>")
        elif msg.status == 102 and not is_passed:
            self.add_info_console("<font color='red'> The case is Failed.</font>")

    def set_case_edit_data(self):
        """
        init data for update case
        :return:
        """
        if not self.case_id:
            return
        self.case = self.dBCommandLineHelper.query_case_by_id(self.case_id)
        self.id_line_edit.setText(self.case_id)
        self.case_name_line_edit.setText(self.case.name)
        tags = ''
        for tag in self.case.tags:
            tags = tags + tag.name + ";"
        self.tag_names_line_edit.setText(tags)
        self.editor_text_edit.setPlainText(self.case.content)

        # 'import' block in the case content
        init_import_set = set()
        for cmd in self.case.content.split("\n"):
            if cmd.strip().find("import") == 0:
                init_import_set.add(cmd.strip())
        # send the init import block to editor's text edit, for init the highlighter and completer
        self.import_list_signal.emit(init_import_set)

    def closeEvent(self, event):
        """
        close window event
        :param event:
        :return:
        """
        case_name = self.case_name_line_edit.text().strip()  # Case Name
        content = self.editor_text_edit.toPlainText().strip()  # Case Content
        tag_list = self.get_tag_list()
        # check case data widget isVisible
        if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible() and (
                not self.case_data_widget.has_modify):
            self.case_data_widget.close()

        if not self.case_id:  # new case
            if (not case_name) and (not content) and (not tag_list):
                self.close()
                return
        elif self.case_id:  # update case
            if not self.check_modify():
                self.close()
                return
        self.handle_message_box_apply(event)

    def handle_message_box_apply(self, event):
        """
        message box
        :param event:
        :return:
        """
        reply = self.message_box.question(self, "Save Changes?", "The case has been modified, save changes?",
                                          QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Discard)

        if reply == QMessageBox.Save:  # update case info
            self.save_case(event)
            # check case data widget isVisible
            if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible():
                self.case_data_widget.close()
        elif reply == QMessageBox.Discard:
            # check case data widget isVisible
            if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible():
                self.case_data_widget.close()
            self.close()
            return
        else:
            self.close_cancel_signal.emit()
            event.ignore()

    def check_modify(self):
        """
        check the changes of the case
        :return:
        """
        is_case_modified = False
        case_db = self.dBCommandLineHelper.query_case_by_id(self.case_id)

        is_name_modified = case_db.name.strip() != self.case_name_line_edit.text().strip()
        is_content_modified = case_db.content.strip() != self.editor_text_edit.toPlainText().strip()

        # tag names in the line edit
        tag_list = self.get_tag_list()
        # tag names in db
        db_tag_list = case_db.tags
        is_tags_names_modify = set(db_tag_list).difference(set(tag_list)) != set(tag_list).difference(set(db_tag_list))

        # check the case data
        if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible():
            self.is_case_data_modify = self.case_data_widget.has_modify

        if is_name_modified or is_content_modified or is_tags_names_modify or self.is_case_data_modify:
            logger.debug('case changed. case name: {}, tags: {}, content: {}, case data: {}'
                         .format(is_name_modified, is_tags_names_modify, is_content_modified, self.is_case_data_modify))
            is_case_modified = True
        return is_case_modified

    def get_tag_list(self):
        """
        get tag list from tag_names_line_edit
        :return:
        """
        # get tag names
        tag_name_list = self.tag_names_line_edit.text().strip().split(";")
        tag_set = set()
        for tag_name in tag_name_list:
            if not tag_name.strip():
                continue
            tag = self.dBCommandLineHelper.query_tag_by_name(tag_name.strip())
            tag_set.add(tag)
        return list(tag_set)

    def run_btn_event(self):
        """
        click run button, show add_device_widget
        :return:
        """
        self.add_device_widget = AddDeviceWidget()  # add device
        self.add_device_widget.setWindowModality(Qt.ApplicationModal)
        self.device_and_data_signal.connect(self.add_device_widget.add_radio_to_widget, Qt.QueuedConnection)
        self.add_device_widget.run_editor_signal.connect(self.run_case, Qt.QueuedConnection)
        devices = []
        if self.is_running:
            self.stop_case()
        try:
            devices = self.tester.devices()
        except Exception as e:
            self.add_info_console("<font color='red'>" + str(e) + "</font>")
        if not devices:  # There is no device connected
            self.message_box.warning(self, "Message", "Please connect the device to your computer.", QMessageBox.Ok)
            return

        # get case data count
        if self.case_id is not None:
            self.case_data_count = self.case_data_manage.get_case_data_count(self.case_id)

        self.device_and_data_signal.emit(devices, self.case_data_count)
        self.add_device_widget.show()

    def run_case(self, devices, data_line_number):
        # change icon
        stop_icon = QIcon()
        stop_icon.addPixmap(QPixmap(self.config.images + '/stop.png'), QIcon.Normal, QIcon.Off)
        self.run_btn.setIcon(stop_icon)
        self.run_btn.setText("Stop")
        self.is_running = True
        if not devices:
            return
        self.tester.select_devices(devices)

        self.data_line = data_line_number
        self.run()  # run

    def stop_case(self):
        # set icon
        run_icon = QIcon()
        run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off)
        self.run_btn.setIcon(run_icon)
        self.run_btn.setText("Run")
        self.is_running = False
        try:
            self.tester.stop()
            self.tester.stop_server()
        except Exception as e:
            self.add_info_console("<font color='red'>" + str(e) + "</font>")

    def run(self):
        """
        run case content
        :return:
        """
        case_content = self.editor_text_edit.toPlainText().strip()

        case_data = None
        try:
            if (self.case_id is not None) and (self.case_data_count > 0):  # case data exist
                case_data = self.case_data_manage.get_run_format_data(self.case_id)  # get all case data

            self.debug_runner.reset()
            self.debug_runner._data = case_data  # set case data
            self.debug_runner.parse(case_content)
            logger.debug("Debug beginning")
            self.debug_runner.execute(case_content, self.data_line)
        except Exception as e:
            logger.exception(str(e))
            self.add_info_console("<font color='red'>" + str(e) + "</font>")
        self.stop_case()

    def save_case(self, event=None):
        """
        save case
        :return:
        """
        case_name = self.case_name_line_edit.text().strip()  # Case Name
        content = self.editor_text_edit.toPlainText()  # Case Content
        if self.check_null():
            if event:
                event.ignore()
            return
        tags = self.get_tag_list()

        if self.check_tag_name():  # check unrecognized tag names
            return

        if self.case_id:
            self.case.name = case_name
            self.case.content = content
            self.case.tags = tags
            try:
                # update case and case data
                if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible():
                    self.case.last_modify_time = datetime.datetime.now()  # update time
                    self.case_manager.update_case(self.case_id, self.case_data_widget.case_data_list,
                                                  self.case_data_widget.delete_data_ids)
                    del self.case_data_widget.delete_data_ids[:]
                    self.case_data_widget.has_modify = False
                else:
                    self.case.last_modify_time = datetime.datetime.now()  # update time
                    self.dBCommandLineHelper.update_case()
            except Exception as e:
                logger.exception(str(e))
                self.message_box.information(self, "Update Case Error", "Update case Fail.\nError Info:\n" + str(e),
                                             QMessageBox.Ok)
        else:
            try:
                # insert case and save case data
                if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible():
                    case = self.case_manager.insert_case(case_name, content, tags, self.case_data_widget.case_data_list,
                                                         self.case_data_widget.delete_data_ids)
                    del self.case_data_widget.delete_data_ids[:]
                    self.case_data_widget.has_modify = False
                else:
                    case = self.dBCommandLineHelper.insert_case_with_tags(case_name, content, tags)
                self.id_line_edit.setText(str(case.id))
                self.case_id = self.id_line_edit.text().strip()
                self.set_case_edit_data()
            except Exception as e:
                logger.exception(str(e))
                self.message_box.information(self, "Add Case Error", "Add case Fail.\nError Info:\n" + str(e),
                                             QMessageBox.Ok)
        self.refresh_signal.emit()  # refresh the main table

    def check_null(self):
        """
        check the required options
        :return:
        """
        is_none = False
        type_info = ''
        case_name = self.case_name_line_edit.text().strip()
        content = self.editor_text_edit.toPlainText().strip()

        if not case_name:
            is_none = True
            type_info += "Case Name"
        if not content:
            is_none = True
            if not type_info:
                type_info += "Content"
            else:
                type_info += ", Content"
        if is_none:
            self.message_box.warning(self, "Message", type_info + " is required.", QMessageBox.Ok)
        return is_none

    def editor_adapter(self):
        """
        get keywords for the completer and the highlighter
        :return:
        """
        if self.case_id:
            self.parse_import_as()
        func_dict = self.debug_runner.core.kw_func  # get default functions
        cmp = Completer(self.debug_runner)
        self.editor_text_edit.set_completer(cmp)

        # highlighter
        kw_list = []
        for func_name, func in func_dict.items():
            kw_list.append(func_name)
        self.high_lighter = MyHighlighter(self.editor_text_edit, kw_list)
        self.editor_text_edit.set_highlighter(self.high_lighter)

    def parse_import_as(self):
        """
        parse all the 'import' and 'as' block in the case content
        :return:
        """
        self.debug_runner.core.kw_func.clear()
        self.debug_runner.core.kw_func = {**self.debug_runner.core.default_func}
        content_list = self.dBCommandLineHelper.query_case_by_id(self.case_id).content.split("\n")
        if not content_list:
            return
        for line in content_list:
            if line.strip().find("import") == 0:  # parse 'import'
                try:
                    self.debug_runner.core.parse_line(line)
                except Exception as e:
                    self.add_info_console("<font color='red'>" + str(e) + "</font>")
            elif " as " in line.strip():  # parse 'as'
                try:
                    self.debug_runner.core.parse_line(line)
                except Exception as e:
                    self.add_info_console("<font color='red'>" + str(e) + "</font>")

    def set_tag_name_completer(self):
        """
        set completer to tag_names_line_edit
        :return:
        """
        # change button icon
        add_icon = QIcon()
        add_icon.addPixmap(QPixmap(self.config.images + '/add.png'), QIcon.Normal, QIcon.Off)
        self.add_tag_button.setIcon(add_icon)
        self.add_tag_button.setToolTip("add tag")

        self.tag_names_line_edit.setPlaceholderText("Tag Names")
        self.tag_layout.insertWidget(0, self.tag_names_line_edit)

        self.tag_list = self.dBCommandLineHelper.query_tag_all()  # get all tags
        tag_name_list = []
        for tag in self.tag_list:
            tag_name_list.append(tag.name)
        cmp = TagCompleter(tag_name_list)
        self.tag_names_line_edit.setCompleter(cmp)

    def check_tag_name(self):
        """
        check tag name,return unrecognized tag names
        :return:
        """
        tag_name_list = self.tag_names_line_edit.text().strip().split(";")
        unrecognized_tag_names = ""
        has_unrecognized = False
        for tag_name in tag_name_list:
            if not tag_name.strip():
                continue
            tag = self.dBCommandLineHelper.query_tag_by_name(tag_name.strip())
            if not tag:
                unrecognized_tag_names += "\"" + tag_name + "\"" + "、"
        if not unrecognized_tag_names:
            return has_unrecognized
        has_unrecognized = True
        unrecognized_tag_names = unrecognized_tag_names[:-1]
        self.message_box.about(self, "Warning", "Tag name: " + unrecognized_tag_names +
                               " unrecognized, please add it first.")
        return has_unrecognized
示例#25
0
class AddCaseWidget(QWidget):
    select_case_signal = pyqtSignal(list, name="select_case_signal")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.dBCommandLineHelper = DBCommandLineHelper()
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'add_case.ui')
        uic.loadUi(ui_file_path, self)

        screen = QDesktopWidget().screenGeometry()
        self.resize(screen.width() / 5 * 2, screen.height() / 5 * 2)

        self.search_button = SearchButton()
        self.tag_names_line_edit = TagLineEdit("tag_names_line_edit",
                                               self.search_button)
        self.tag_names_line_edit_adapter()
        self.tag_list = None

        self.result_widget = RunnerTableWidget(
            self.dBCommandLineHelper.query_case_all(), [])
        self.result_table_layout.insertWidget(0, self.result_widget)

        self.message_box = QMessageBox()

        self.search_button.clicked.connect(self.search_event)
        self.selectcasebtn.clicked.connect(self.select_event)
        self.casecancelbtn.clicked.connect(self.close)

    def search_event(self):
        """
        search tags by tag name, and show the result in the table widget
        :return:
        """
        self.result_widget.setParent(None)
        self.result_table_layout.removeWidget(self.result_widget)
        tag_names = self.tag_names_line_edit.text().strip()
        # tag_names is None
        if not tag_names:
            case_list = self.dBCommandLineHelper.query_case_all()
            self.result_widget = RunnerTableWidget(case_list, [])
            self.result_table_layout.insertWidget(0, self.result_widget)
            return

        # tag_names is not None
        tag_names = tag_names.split(';')
        for tag_name in tag_names:
            if not tag_name.strip():  # remove null tag
                tag_names.remove(tag_name.strip())
                continue
        case_list = self.dBCommandLineHelper.query_case_by_tag_names(
            [tag_name.strip() for tag_name in tag_names])
        self.result_widget = RunnerTableWidget(case_list, [])
        self.result_table_layout.insertWidget(0, self.result_widget)

    def select_event(self):
        """
        handle the select event
        :return:
        """
        self.result_widget.get_checked_data()
        if not self.result_widget.checked_cases_message:
            self.message_box.warning(self, "Message",
                                     "Please choose cases first.",
                                     QMessageBox.Ok)
            return
        id_list = []
        for item in self.result_widget.checked_cases_message:
            id_list.append(int(item["case_id"]))
        self.select_case_signal.emit(id_list)
        self.close()  # close AddCase

    def tag_names_line_edit_adapter(self):
        """
        settings for tag_names_line_edit
        such as completer, placeholder text
        :return:
        """
        self.tag_names_line_edit.setPlaceholderText("Tag names")
        self.search_layout.insertWidget(0, self.tag_names_line_edit)

        self.tag_list = self.dBCommandLineHelper.query_tag_all(
        )  # get all tags
        tag_name_list = []
        for tag in self.tag_list:
            tag_name_list.append(tag.name)
        cmp = TagCompleter(tag_name_list)
        self.tag_names_line_edit.setCompleter(cmp)
示例#26
0
class RunWidget(QWidget):
    running = False
    device_list_signal = pyqtSignal(list, name="device_list_signal")
    cases = []

    def __init__(self, tester, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'case_run.ui')
        uic.loadUi(ui_file_path, self)

        # set icon
        run_icon = QIcon()
        self.tester = tester
        self.config = self.tester.get_config()

        run_icon.addPixmap(QPixmap(self.config.images + '/run.png'),
                           QIcon.Normal, QIcon.Off)
        self.run_stop_btn.setIcon(run_icon)

        add_icon = QIcon()
        add_icon.addPixmap(QPixmap(self.config.images + '/add.png'),
                           QIcon.Normal, QIcon.Off)
        self.addbtn.setIcon(add_icon)

        self.message_box = QMessageBox()

        self.dBCommandLineHelper = DBCommandLineHelper()

        self.addbtn.clicked.connect(self.click_add_case)
        self.run_stop_btn.clicked.connect(self.click_run_stop_btn)

        self.add_case_widget = None
        self.add_device_widget = None

        self.splitter = None
        self.case_widget = RunnerTableWidget([], [0])
        self.log_area = Console()
        self.splitter_setting()

        self.status_listener = CaseRunStatusListener()
        self.status_listener.listener_msg_signal.connect(
            self.update_case_name_color, Qt.QueuedConnection)
        self.tester.add_run_status_listener(self.status_listener)

    def splitter_setting(self):
        """
        set splitter
        :return:
        """
        if self.splitter:
            self.splitter = None
        self.splitter = QSplitter(Qt.Vertical)
        self.splitter.setHandleWidth(1)
        # add "case_widget" and "log_area" to splitter
        self.splitter.addWidget(self.case_widget)
        self.splitter.addWidget(self.log_area)

        # set the initial scale: 4:1
        self.splitter.setStretchFactor(0, 4)
        self.splitter.setStretchFactor(1, 1)
        self.case_table_layout.addWidget(self.splitter)

    def click_add_case(self):
        """
        click the button to show add case widget
        :return:
        """
        self.add_case_widget = AddCaseWidget()
        self.add_case_widget.select_case_signal.connect(
            self.show_cases, Qt.QueuedConnection)
        self.add_case_widget.setWindowModality(Qt.ApplicationModal)
        self.add_case_widget.show()

    def click_run_stop_btn(self):
        """
        start or stop to run case
        :return:
        """
        devices = []
        if self.running:
            self.stop_case()
            return
        if not self.cases:  # cases is null
            self.message_box.warning(self, "Message",
                                     "Please add cases first.", QMessageBox.Ok)
            return
        try:
            devices = self.tester.devices()
        except Exception as e:
            self.add_log("<font color='red'>" + str(e) + "</font>")
        if not devices:  # There is no device connected
            self.message_box.warning(
                self, "Message", "Please connect the device to your computer.",
                QMessageBox.Ok)
            return
        self.add_device_widget = AddDeviceWidget()
        self.add_device_widget.setWindowModality(Qt.ApplicationModal)
        self.add_device_widget.add_log_signal.connect(self.add_log,
                                                      Qt.QueuedConnection)
        self.add_device_widget.run_case_signal.connect(self.run_case,
                                                       Qt.QueuedConnection)
        self.device_list_signal.connect(
            self.add_device_widget.add_radio_to_widget, Qt.QueuedConnection)
        self.add_device_widget.show()
        try:
            self.device_list_signal.emit(devices)
        except Exception as e:
            self.add_log("<font color='red'><pre>" + str(e) + "</pre></font>")

    def add_log(self, log_info):
        """
        add log to log_area
        :return:
        """
        if self.log_area is None:
            return
        self.log_area.append(log_info)

    def update_case_name_color(self, msg, is_passed):
        """
        update case's font color according to the case's result
        pass: green; fail: red
        :param is_passed:
        :param msg:
        :return:
        """
        if msg.status == 601:
            self.add_log("<font color='green'> Start to install agent.</font>")
        elif msg.status == 602:
            self.add_log("<font color='green'> Install agent success.</font>")
        elif msg.status == 603:
            self.add_log("<font color='red'> Install agent Fail." +
                         "\r Error Info:\r<pre>" + msg.message +
                         "</pre></font>")
        elif msg.status == 701:
            self.add_log("<font color='green'> Start agent.</font>")
        elif msg.status == 702:
            self.add_log("<font color='green'> Stop agent.</font>")
        elif msg.status == 703:
            self.add_log("<font color='red'> Agent error." +
                         "\r Error Info:\r<pre>" + msg.message +
                         "</pre></font>")

        for row_index in range(self.case_widget.dataTableWidget.rowCount()):
            case_id_item = self.case_widget.dataTableWidget.item(
                row_index, 1)  # get case id from dataTableWidget
            if msg.status == 2:  # test end
                if is_passed:
                    self.add_log(
                        "<font color='green'> All cases are Passed.</font>")
                self.stop_case()
                break
            if case_id_item.text() != str(msg.case_id):
                continue
            self.case_widget.dataTableWidget.selectRow(row_index)
            if msg.status == 101:  # default: case pass
                self.update_green(row_index)
            elif msg.status == 500:
                self.update_red(row_index)
                self.add_log("<font color='red'> Case Failed, case id: " +
                             str(msg.case_id) + "</font>")
                self.add_log("<pre><font color='red'>" + str(msg.message) +
                             "</font></pre>")

    def run_case(self, devices):
        kw_case_list = []
        if not self.cases:
            return
        for case_id in self.cases:
            kw_case = KWCase()
            case = self.dBCommandLineHelper.query_case_by_id(case_id)
            kw_case.id = case.id
            kw_case.name = case.name
            kw_case.content = case.content
            kw_case.data = case.data
            kw_case_list.append(kw_case)
        # set icon
        stop_icon = QIcon()
        stop_icon.addPixmap(QPixmap(self.config.images + '/stop.png'),
                            QIcon.Normal, QIcon.Off)
        self.run_stop_btn.setIcon(stop_icon)
        self.run_stop_btn.setText("Stop")
        self.running = True
        if not devices:
            return
        try:
            self.tester.select_devices(devices)
            self.tester.run(kw_case_list)
        except Exception as e:
            self.stop_case()
            self.add_log(str(e))

    def stop_case(self):
        run_icon = QIcon()
        run_icon.addPixmap(QPixmap(self.config.images + '/run.png'),
                           QIcon.Normal, QIcon.Off)
        self.run_stop_btn.setIcon(run_icon)  # change icon
        self.run_stop_btn.setText("Run")
        self.running = False
        try:
            self.tester.stop()
            self.tester.stop_server()
        except Exception as e:
            self.add_log(str(e))

    def show_cases(self, id_list):
        """
        show cases in RunnerTableWidget according to id list
        :param id_list:
        :return:
        """
        self.case_table_layout.removeWidget(self.splitter)
        case_list = []
        self.cases = id_list
        for case_id in id_list:
            case = self.dBCommandLineHelper.query_case_by_id(case_id)
            case_list.append(case)
        self.case_widget = RunnerTableWidget(case_list, [0])
        self.splitter_setting()  # reload splitter
class CaseDataManager:
    def __init__(self):
        self.db_helper = DBCommandLineHelper()

    def get_case_data_count(self, case_id):
        case_data_list = self.get_run_format_data(case_id)
        return len(case_data_list)

    def get_case_data(self, case_id):
        case_data_list = []
        case = self.db_helper.query_case_by_id(case_id)
        header_relation_list = eval(case.header_relation) if case.header_relation else []
        case_data_list.append(header_relation_list)
        if case.data_relation is not None and case.data_relation:
            data_relation_list = eval(case.data_relation)
            for data_relation in data_relation_list:
                temp_data_list = []
                for data_id in data_relation:
                    case_data = CaseData()
                    if data_id:
                        temp_case_data = self.db_helper.query_case_data(id=int(data_id))
                        case_data.id = temp_case_data.id
                        case_data.data = temp_case_data.data
                        case_data.init_data = temp_case_data.data
                    temp_data_list.append(case_data)
                case_data_list.append(temp_data_list)
        return case_data_list

    def get_run_format_data(self, case_id):
        case_data_list = []
        data_dict = self.filter_data(case_id)
        new_data_relation_list = data_dict['new_data_relation']
        key_name = data_dict['key_name']
        if new_data_relation_list:  # 格式化过滤后的数据
            case_data_list = self.get_format_data_row(new_data_relation_list, key_name)
        return case_data_list

    def filter_data(self, case_id):
        data_dict = {}
        new_data_relation_list = []
        case = self.db_helper.query_case_by_id(case_id)
        key_name = []
        key_index = []
        if case.header_relation and case.data_relation:
            data_relation_list = eval(case.data_relation)
            header_relation_list = eval(case.header_relation)
            # 获取header
            for index, key in enumerate(header_relation_list):
                if key:
                    key_index.append(index)
                    key_name.append(key)
            if key_index and data_relation_list:
                for data_relation in data_relation_list:
                    new_data_relation = []
                    for index in key_index:
                        new_data_relation.append(data_relation[index])
                    if not self.is_empty_list(new_data_relation):  # 去除空行
                        new_data_relation_list.append(new_data_relation)
        data_dict['key_name'] = key_name
        data_dict['new_data_relation'] = new_data_relation_list
        return data_dict

    def is_empty_list(self, data_list):
        data_str = ''.join(data_list)
        if data_str:
            return False
        else:
            return True

    def get_format_data_row(self, data_relation_list, key_name):
        '''
        获取运行 case data 格式化
        :param data_relation_list:
        :param key_name:
        :return:
        '''
        case_data_list = []
        for new_data_relation in data_relation_list:
            case_data_dict = {}
            for index, data_id in enumerate(new_data_relation):
                if data_id:
                    case_data = self.db_helper.query_case_data(id=int(data_id))
                    case_data_dict[key_name[index]] = case_data.data
                else:
                    case_data_dict[key_name[index]] = ''
                data = DataRow()
                data.__dict__ = case_data_dict
            case_data_list.append(data)
        return case_data_list

    def get_format_case_data(self, row_count, column_count, case_id):
        '''
        table 展示case data 格式化
        :param row_count:
        :param column_count:
        :param case_id:
        :return:
        '''
        case_data_list = []
        db_case_data_list = []
        if case_id:
            db_case_data_list = self.get_case_data(case_id)
        # header:
        db_case_data_len = len(db_case_data_list)
        for row_num in range(0, row_count):
            temp_list = []
            for column_num in range(0, column_count):
                if db_case_data_list and row_num < db_case_data_len and column_num < len(db_case_data_list[row_num]):
                    temp_list.append(db_case_data_list[row_num][column_num])
                else:
                    if row_num == 0:
                        temp_list.append('')
                    else:
                        temp_list.append(CaseData())
            case_data_list.append(temp_list)
        return case_data_list

    def save_case_data(self, case_id, case_data_list, delete_data_ids):
        case = self.db_helper.query_case_by_id(case_id)
        case_relation_list = []
        header_relation_list = case_data_list[0]
        for case_data in case_data_list[1:]:
            for case_data_detail in case_data:
                # if type(case_data_detail) == CaseData:
                if case_data_detail.id and case_data_detail.data != case_data_detail.init_data and case_data_detail.data != '':  # 修改
                    self.db_helper.update_case_data(case_data_detail.id, case_data_detail.data)
                elif case_data_detail.data == '' or case_data_detail.data is None and case_data_detail.id:  # 删除
                    self.db_helper.delete_case_data(id=case_data_detail.id)
                    case_data_detail.id = None
                    case_data_detail.data = ''
                elif case_data_detail.id is None and case_data_detail.data:  # 添加 检验id 值
                    add_case_data = self.db_helper.insert_case_data(data=case_data_detail.data)
                    case_data_detail.id = add_case_data.id
                case_data_detail.init_data = case_data_detail.data
        # 获取 case relation
        for case_data in case_data_list[1:]:
            temp_list = []
            for case_data_detail in case_data:
                if type(case_data_detail) == CaseData:
                    id = '' if case_data_detail.id is None else str(case_data_detail.id)
                    temp_list.append(id)
                else:
                    temp_list.append(case_data_detail)
            case_relation_list.append(temp_list)
        case.data_relation = self.list_to_str(case_relation_list, 2)
        case.header_relation = self.list_to_str(header_relation_list, 1)
        self.db_helper.update_case()
        # 删除 case data
        if delete_data_ids:
            self.db_helper.batch_delete_case_data(delete_data_ids)

    def list_to_str(self, data_list, dimension):
        '''
        two-dimensional array to string
        string [[],[],[]]
        :return:
        '''

        if dimension == 1:  # 一维数组
            data_relation_str = '['
            for column in data_list:
                data_relation_str = data_relation_str + '\'' + column + '\','
            data_relation_str = data_relation_str[:len(data_relation_str) - 1]
            data_relation_str += ']'
            return data_relation_str
        elif dimension == 2:  # 二维数组
            data_relation_str = '['
            for data in data_list:
                data_relation_str += '['
                for column in data:
                    data_relation_str = data_relation_str + '\'' + column + '\','
                data_relation_str = data_relation_str[:len(data_relation_str) - 1]
                data_relation_str += '],'
            data_relation_str = data_relation_str[:len(data_relation_str) - 1]
            data_relation_str += ']'
            return data_relation_str
        else:
            pass
示例#28
0
                tag_names = tag_names + ',' + tag.name
            self.setItem(row, 4, QTableWidgetItem(tag_names[1:]))
        self.resizeColumnsToContents()  # Adjust the width according to the content
        self.horizontalHeader().setStretchLastSection(True)

    def horsection_clicked(self, index):
        if index == 0:
            if self.check_all:
                check_status = Qt.Unchecked
                self.check_all = False
            else:
                check_status = Qt.Checked
                self.check_all = True
            for row in range(0, self.rowCount()):
                check_box_item = self.item(row, 0)
                check_box_item.setCheckState(check_status)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    db_helper = DBCommandLineHelper()
    case_list = db_helper.query_case_by_tag_names(['我的'])
    # table_widget = RunnerTableWidget(case_list,[0,1])#隐藏第0/1列
    table_widget = RunnerTableWidget(case_list)  # 全部展示
    dict = table_widget.get_checked_data()  # 获取选中的checkbox
    window = QMainWindow()
    window.resize(500, 500)
    window.setCentralWidget(table_widget)
    window.show()
    app.exec_()
示例#29
0
class TagEditorWidget(QWidget):
    def __init__(self, refresh_signal, tag_name=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.refresh_signal = refresh_signal
        self.db_helper = DBCommandLineHelper()
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'tag_editor.ui')
        uic.loadUi(ui_file_path, self)
        # set icon
        save_icon = QIcon()
        config = Config()
        save_icon.addPixmap(QPixmap(config.images + '/save.png'), QIcon.Normal, QIcon.Off)
        self.tag_save_btn.setIcon(save_icon)
        self.tag_save_btn.clicked.connect(self.tag_save)
        self.tag_id_line_edit.hide()  # 隐藏line_edit
        self.tag_name_line_edit.setPlaceholderText("Tag Name")  # 设置提示文字
        self.tag_description_text_edit.setPlaceholderText('Tag Description')
        if tag_name:
            self.tag = self.db_helper.query_tag_by_name(tag_name)
            self.tag_id_line_edit.setText(str(self.tag.id))
            self.tag_name_line_edit.setText(self.tag.name)
            self.tag_description_text_edit.setPlainText(self.tag.description)
            # self.tag_description_text_edit.setDocument(QTextDocument("Tag description"))  # 设置提示文字

    def closeEvent(self, close_even):
        if self.tag_id_line_edit.text() != '':
            if self.tag.name != self.tag_name_line_edit.text() or self.tag.description != self.tag_description_text_edit.toPlainText():
                reply = QMessageBox.information(self, 'close window', 'Changes not saved, confirm close?',
                                                QMessageBox.Yes, QMessageBox.No)
                if reply != QMessageBox.Yes:
                    close_even.ignore()
                    return
        else:
            if self.tag_id_line_edit.text() != '' or self.tag_description_text_edit.toPlainText() != '':
                reply = QMessageBox.information(self, 'close window', 'Changes not saved, confirm close?',
                                                QMessageBox.Yes, QMessageBox.No)
                if reply != QMessageBox.Yes:
                    close_even.ignore()
                    return
        self.refresh_signal.emit()

    def tag_save(self):
        tag_id = self.tag_id_line_edit.text()
        tag_name = self.tag_name_line_edit.text()
        tag_description = self.tag_description_text_edit.toPlainText()
        if tag_name == '' or tag_description == '':
            QMessageBox.warning(self, 'tag editor', 'tag name and description can\'t be empty')
        else:
            if len(tag_name) > 8:
                QMessageBox.warning(self, 'tag editor', 'tag name is not greater than 8 characters')
            else:
                if tag_id:
                    self.tag.name = tag_name
                    self.tag.description = tag_description
                    self.db_helper.update_tag()
                    QMessageBox.information(self, 'tag editor', 'tag update success')#todo 是否添加刷新
                else:
                    tag = self.db_helper.query_tag_by_name(tag_name)
                    if tag is None:
                        tag = self.db_helper.insert_tag(tag_name, tag_description)
                        self.tag_id_line_edit.setText(str(tag.id))
                        self.tag = tag
                        QMessageBox.information(self, 'tag editor', 'tag insert success')#todo 是否添加刷新
                    else:
                        QMessageBox.warning(self, 'tag editor', 'tag has existed')
示例#30
0
class CaseManager:
    CASE_TABLE_NAME = "case"
    TAG_TABLE_NAME = "tag"
    CASE_TAG_TABLE_NAME = "case_tag"
    CASE_DATA_TABLE_NAME = "case_data"

    CASE_TABLE_NAME_FILE = CASE_TABLE_NAME + ".csv"
    TAG_TABLE_NAME_FILE = TAG_TABLE_NAME + ".csv"
    CASE_TAG_TABLE_NAME_FILE = CASE_TAG_TABLE_NAME + ".csv"
    CASE_DATA_TABLE_NAME_FILE = CASE_DATA_TABLE_NAME + ".csv"

    db_helper = DBCommandLineHelper()
    tag_file_data = []
    case_tag_file_data = []
    case_file_data = []
    case_data_file_data = []
    conflict_tag_name = []
    conflict_tag_message_dict = []

    def __init__(self):
        self.case_data_manager = CaseDataManager()

    def update_case(self, case_id, case_data_list,
                    delete_data_ids):
        '''
        更新case
        :return:
        '''
        self.db_helper.update_case()
        self.case_data_manager.save_case_data(case_id, case_data_list,
                                              delete_data_ids)

    def insert_case(self, case_name, content, tags, case_data_list,
                    delete_data_ids):
        '''
        插入case
        :return:
        '''
        case = self.db_helper.insert_case_with_tags(case_name, content, tags)
        self.case_data_manager.save_case_data(case.id, case_data_list,
                                              delete_data_ids)
        return case

    # 解压zip文件
    def unzip(self, path):
        zip = zipfile.ZipFile(path)
        filelist = zip.namelist()
        for file in filelist:
            f_handle = open(file, "wb")
            f_handle.write(zip.read(file))
            f_handle.close()
        zip.close()

    # 添加文件到已有的zip包中
    def addzip(self, path):
        f = zipfile.ZipFile(path, 'w', zipfile.ZIP_DEFLATED)
        f.write(self.CASE_TABLE_NAME_FILE)
        f.write(self.TAG_TABLE_NAME_FILE)
        f.write(self.CASE_TAG_TABLE_NAME_FILE)
        f.write(self.CASE_DATA_TABLE_NAME_FILE)
        f.close()
        self.remove_data_file()

    def remove_data_file(self):
        os.remove(os.path.join(os.getcwd(), self.CASE_TABLE_NAME_FILE))
        os.remove(os.path.join(os.getcwd(), self.TAG_TABLE_NAME_FILE))
        os.remove(os.path.join(os.getcwd(), self.CASE_TAG_TABLE_NAME_FILE))
        os.remove(os.path.join(os.getcwd(), self.CASE_DATA_TABLE_NAME_FILE))

    def export_data(self, path, case_id_list):
        cases_id = ','.join(case_id_list)
        result = self.db_helper.get_table_data_by_cases_id(cases_id)
        self.trans_to_csv(result)
        self.addzip(path)

    def trans_to_csv(self, result):
        case_data_frame = pd.DataFrame(data=list(result[self.CASE_TABLE_NAME]),
                                       columns=result[self.CASE_TABLE_NAME].keys())
        case_data_frame.to_csv(os.path.join(os.getcwd(), self.CASE_TABLE_NAME_FILE), encoding="utf-8", index=False)

        tag_data_frame = pd.DataFrame(data=list(result[self.TAG_TABLE_NAME]),
                                      columns=result[self.TAG_TABLE_NAME].keys())
        tag_data_frame.to_csv(os.path.join(os.getcwd(), self.TAG_TABLE_NAME_FILE), encoding="utf-8", index=False)

        case_tag_data_frame = pd.DataFrame(data=list(result[self.CASE_TAG_TABLE_NAME]),
                                           columns=result[self.CASE_TAG_TABLE_NAME].keys())
        case_tag_data_frame.to_csv(os.path.join(os.getcwd(), self.CASE_TAG_TABLE_NAME_FILE), encoding="utf-8",
                                   index=False)

        case_data_data_frame = pd.DataFrame(data=list(result[self.CASE_DATA_TABLE_NAME]),
                                            columns=result[self.CASE_DATA_TABLE_NAME].keys())

        case_data_data_frame.to_csv(os.path.join(os.getcwd(), self.CASE_DATA_TABLE_NAME_FILE), encoding="utf-8",
                                    index=False)

    # 导入数据
    def import_data(self, path):
        self.unzip(path)
        self.tag_file_data = pd.read_csv(os.path.join(os.getcwd(), self.TAG_TABLE_NAME_FILE))
        self.case_tag_file_data = pd.read_csv(os.path.join(os.getcwd(), self.CASE_TAG_TABLE_NAME_FILE))
        self.case_tag_file_data['has_changed'] = False
        self.case_file_data = pd.read_csv(os.path.join(os.getcwd(), self.CASE_TABLE_NAME_FILE))
        self.case_data_file_data = pd.read_csv(os.path.join(os.getcwd(), self.CASE_DATA_TABLE_NAME_FILE))

        self.remove_data_file()
        self.check_data()
        if self.conflict_tag_message_dict:
            return self.conflict_tag_message_dict
        else:
            self.merge_data()
            return None

    def merge_conflict_data_callback(self, updata_tag_message_list, callback):
        result = self.merge_conflict_data(updata_tag_message_list)
        callback(result)

    # 返回冲突修改后的信息 进行数据合并
    def merge_conflict_data(self, updata_tag_message_list):
        for tag_message in updata_tag_message_list:
            self.tag_file_data.loc[self.tag_file_data["id"] == tag_message['id'], 'name'] = tag_message['name']
            self.tag_file_data.loc[self.tag_file_data["id"] == tag_message['id'], 'description'] = tag_message[
                'description']
        self.merge_data()
        return True

    def check_data(self):
        tag_data = self.db_helper.get_table_data(self.TAG_TABLE_NAME)
        tag_db_data = pd.DataFrame(data=list(tag_data), columns=tag_data.keys())
        del self.conflict_tag_name[:]
        for name in self.tag_file_data['name']:  # 获取冲突tag名称
            if name in tag_db_data['name'].values:
                self.conflict_tag_name.append(name)
        if len(self.conflict_tag_name) > 0:  # 获取tag冲突详细信息
            conflict_message_frame = tag_db_data[tag_db_data["name"].isin(self.conflict_tag_name)]
            src_tag_message_frame = self.tag_file_data[self.tag_file_data["name"].isin(self.conflict_tag_name)]
            conflict_message_frame.loc[:, 'src_id'] = src_tag_message_frame["id"].values
            conflict_message_frame.loc[:, 'src_name'] = src_tag_message_frame["name"].values
            conflict_message_frame.loc[:, 'src_description'] = src_tag_message_frame[
                "description"].values
            self.conflict_tag_message_dict = conflict_message_frame.T.to_dict()
        return self.conflict_tag_message_dict

    # 合并数据
    def merge_data(self):
        for i in range(len(self.tag_file_data)):
            old_tag_id = self.tag_file_data["id"][i]
            tag_name = self.tag_file_data["name"][i]
            tag = self.db_helper.query_tag_by_name(tag_name)
            # 检查tag是否存在 存在的不插入 获取ID ,不存在的插入 生成ID
            if tag is None:
                tag_description = self.tag_file_data["description"][i]
                tag = self.db_helper.insert_tag(tag_name, tag_description)
            new_tag_id = tag.id
            self.case_tag_file_data.loc[
                (self.case_tag_file_data['tag_id'] == old_tag_id) & (self.case_tag_file_data['has_changed'] == False), [
                    'tag_id', 'has_changed']] = [new_tag_id, True]

        # 插入case data:
        data_id_dict = {}
        for i in range(len(self.case_data_file_data)):
            old_data_id = self.case_data_file_data['id'][i]
            data = self.case_data_file_data['data'][i]
            case_data = self.db_helper.insert_case_data(data)
            new_data_id = case_data.id
            data_id_dict[old_data_id] = new_data_id

        # 插入case 插入case_tag
        case_list = []
        for i in range(len(self.case_file_data)):
            old_case_id = self.case_file_data["id"][i]
            tag_ids = self.case_tag_file_data[self.case_tag_file_data["case_id"] == old_case_id]["tag_id"].values
            tags = []
            for tag_id in tag_ids:
                tag = self.db_helper.query_tag_by_id(int(tag_id))
                tags.append(tag)
            case = Case()
            case.name = self.case_file_data["name"][i]
            case.content = self.case_file_data["content"][i]
            case.tags = tags
            case.header_relation = self.case_file_data["header_relation"][i]
            # data_relation 更新
            if self.case_file_data["data_relation"][i] and type(self.case_file_data["data_relation"][i]) is str:
                data_relation_list = eval(self.case_file_data["data_relation"][i])
                # if len(data_relation_list) > 1:
                for data_relation in data_relation_list:
                    for index,data_id in enumerate(data_relation):
                        if data_id and data_id_dict[int(data_id)]:
                            # index = data_relation.index(data_id)
                            data_relation[index] = str(data_id_dict[int(data_id)])
                case.data_relation = self.case_data_manager.list_to_str(data_relation_list,2)
                # self.case_file_data["data_relation"][i] = case.data_relation
            case_list.append(case)
        self.db_helper.batch_insert_case_with_tags(case_list)

    def add_tag(self, tag_name, tag_description):
        # TODO 前端确保标识不存在
        result = {}
        tag = self.db_helper.query_tag_by_name(tag_name)
        if tag:
            result['status'] = -1
            result['message'] = '标识已存在'
        else:
            self.db_helper.insert_tag(tag_name, tag_description)
            result['status'] = 0
            result['message'] = '标识插入成功'
        return result

    def query_case_data(self, case=None, case_id=None):
示例#31
0
 def setUp(self):
     self.db_helper = DBCommandLineHelper()
示例#32
0
    def __init__(self, refresh_signal, tester, case_id=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'case_editor.ui')
        uic.loadUi(ui_file_path, self)

        self.dBCommandLineHelper = DBCommandLineHelper()
        self.tester = tester
        self.config = self.tester.get_config()
        self.debug_runner = self.tester.get_debug_runner()
        self.case_id = case_id
        self.refresh_signal = refresh_signal

        self.init_ui()

        self.is_log_show = True
        self.is_running = False
        self.tag_list = []
        self.parsed_line_list = []
        self.case = None
        self.high_lighter = None
        self.tag_manage_widget = None
        self.add_device_widget = None

        self.message_box = QMessageBox()
        self.add_tag_button = SearchButton()
        self.tag_names_line_edit = TagLineEdit("tag_names_line_edit", self.add_tag_button)
        self.set_tag_name_completer()

        self.splitter = QSplitter(Qt.Vertical)

        self.splitter.setHandleWidth(1)  # set handle width
        self.editor_text_edit = TextEdit(self.debug_runner.core)  # case content TextEdit
        self.console = Console()

        # Add the 'editor text edit' and 'console' to splitter
        self.splitter.addWidget(self.editor_text_edit)
        self.splitter.addWidget(self.console)

        # Set the initial scale: 4:1
        self.splitter.setStretchFactor(0, 4)
        self.splitter.setStretchFactor(1, 1)

        self.editor_layout.addWidget(self.splitter)

        self.import_list_signal.connect(self.editor_text_edit.get_import_from_content, Qt.QueuedConnection)
        self.editor_text_edit.parse_error_info_signal.connect(self.add_info_console, Qt.QueuedConnection)

        self.editor_adapter()  # set completer and highlighter
        self.set_case_edit_data()  # update case

        # run status listener
        self.status_listener = EditorRunStatusListener()
        self.status_listener.editor_listener_msg_signal.connect(self.result_handle, Qt.QueuedConnection)
        self.debug_runner.listener = self.status_listener

        self.data_line = None

        # button event
        self.save_btn.clicked.connect(self.save_case)
        self.run_btn.clicked.connect(self.run_btn_event)
        self.console_btn.clicked.connect(self.log_show_hide_event)
        self.edit_data_btn.clicked.connect(self.add_case_data)
        self.add_tag_button.clicked.connect(self.choose_event)
        # case data
        self.case_manager = CaseManager()
        self.case_data_manage = CaseDataManager()
        self.case_data_count = 0  # init case data count
        self.is_case_data_modify = False
示例#33
0
class TagManageWidget(QWidget):
    selected_tag_names_signal = pyqtSignal(str, name="selected_tag_names_signal")
    refresh_signal = pyqtSignal(name="refresh_signal")

    def __init__(self, config, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ui_dir_path = os.path.dirname(__file__)
        ui_file_path = os.path.join(ui_dir_path, 'tag_manage_widget.ui')
        uic.loadUi(ui_file_path, self)

        self.db_helper = DBCommandLineHelper()
        self.message_box = QMessageBox()

        self.tag_names_line_edit = TagNamesLineEdit()
        self.tag_names_line_edit.setPlaceholderText("Tag Names")
        self.cmp = None
        self.set_completer()
        self.selected_tag_names_layout.insertWidget(0, self.tag_names_line_edit)

        add_icon = QIcon()
        add_icon.addPixmap(QPixmap(config.images + '/add.png'), QIcon.Normal, QIcon.Off)
        self.new_tag_btn.setIcon(add_icon)
        self.tag_editor = None
        self.tag_list = None
        self.set_tag_list_widget()   # init data

        self.select_btn.clicked.connect(self.select_event)
        self.cancel_btn.clicked.connect(self.close)
        self.new_tag_btn.clicked.connect(self.new_tag_event)

        self.refresh_signal.connect(self.set_tag_list_widget, Qt.QueuedConnection)

    def new_tag_event(self):
        """
        show tag editor
        :return:
        """
        self.tag_editor = TagEditorWidget(self.refresh_signal)
        self.tag_editor.setWindowModality(Qt.ApplicationModal)
        self.tag_editor.show()

    def select_event(self):
        """
        handle select event
        :return:
        """
        selected_tag_names = self.tag_names_line_edit.text().strip()
        if not selected_tag_names:
            self.close()
            return
        if self.check_tag_name():
            return
        self.selected_tag_names_signal.emit(selected_tag_names)
        self.close()

    def set_tag_list_widget(self):
        """
        init tag_list_widget data and onclick event
        :return:
        """
        self.tag_list_widget.clear()
        self.tag_list = self.db_helper.query_tag_all()
        for tag in self.tag_list:
            self.tag_list_widget.addItem(tag.name)
        self.tag_list_widget.itemClicked.connect(
            lambda: self.list_widget_item_clicked(self.tag_list_widget.currentItem()))
        item = self.tag_list_widget.item(0)
        if not item:
            return
        item.setSelected(True)
        self.set_completer()   # reset completer's tag name list

    def list_widget_item_clicked(self, tag_list_widget_item):
        """
        handle list widget item click event
        :param tag_list_widget_item:
        :return:
        """
        tag_name_set = set()
        selected_tag_names = ""

        selected_line_edit_text = self.tag_names_line_edit.text().strip()
        tag_names_list = selected_line_edit_text.split(";")

        # origin tag names
        for tag_name in tag_names_list:
            if tag_name.strip():
                tag_name_set.add(tag_name.strip() + ";")
        tag_name_set.add(tag_list_widget_item.text() + ';')  # add clicked tag name

        for tag_name in tag_name_set:
            selected_tag_names += tag_name
        self.tag_names_line_edit.is_completer = False
        self.tag_names_line_edit.clear()
        self.tag_names_line_edit.setText(selected_tag_names)
        self.tag_names_line_edit.is_completer = True

    def check_tag_name(self):
        """
        check tag name,return unrecognized tag names
        :return:
        """
        tag_name_list = self.tag_names_line_edit.text().strip().split(";")
        unrecognized_tag_names = ""
        has_unrecognized = False
        for tag_name in tag_name_list:
            if not tag_name.strip():
                continue
            tag = self.db_helper.query_tag_by_name(tag_name.strip())
            if not tag:
                unrecognized_tag_names += "\"" + tag_name + "\"" + "、"
        if not unrecognized_tag_names:
            return has_unrecognized
        has_unrecognized = True
        unrecognized_tag_names = unrecognized_tag_names[:-1]
        self.message_box.about(self, "Warning", "Tag name: " + unrecognized_tag_names +
                               " unrecognized, please add it first.")
        return has_unrecognized

    def set_completer(self):
        """
        set completer to tag_names_line_edit
        :return:
        """
        self.tag_list = self.db_helper.query_tag_all()  # get all tag
        tag_name_list = []
        for tag in self.tag_list:
            tag_name_list.append(tag.name)
        cmp = TagCompleter(tag_name_list)
        self.tag_names_line_edit.setCompleter(cmp)