diff --git a/ApiAutomationTest/app/cores/case/http/http_cookie_pool_manager.py b/ApiAutomationTest/app/cores/case/http/http_cookie_pool_manager.py index 0654dc3..5bf8caa 100644 --- a/ApiAutomationTest/app/cores/case/http/http_cookie_pool_manager.py +++ b/ApiAutomationTest/app/cores/case/http/http_cookie_pool_manager.py @@ -69,19 +69,19 @@ class HTTPCookiePoolManager: if old_rcj is None: __class__.ScheduleCookiePool[project_id] = rcj else: - cls._update_request_cookie_jar(old_rcj=old_rcj, new_rcj=rcj) + cls.update_request_cookie_jar(old_rcj=old_rcj, new_rcj=rcj) else: session_id = session_id_manager.get_session_id() old_rcj = __class__.CookiePool[session_id][type] if old_rcj is None: __class__.CookiePool[session_id][type] = rcj else: - cls._update_request_cookie_jar(old_rcj=old_rcj, new_rcj=rcj) + cls.update_request_cookie_jar(old_rcj=old_rcj, new_rcj=rcj) else: raise ValueError('不支持传入type值为%s,只支持type=single_case 或 type=build_case' % type) @classmethod - def _update_request_cookie_jar(cls, old_rcj: RequestsCookieJar, new_rcj: RequestsCookieJar): + def update_request_cookie_jar(cls, old_rcj: RequestsCookieJar, new_rcj: RequestsCookieJar): """将新的rcj更新到老的rcj上""" old_rcj.update(other=new_rcj) @@ -107,7 +107,7 @@ class HTTPCookiePoolManager: }) @classmethod - def get_request_cookie_jar(cls, type: str) -> Optional[RequestsCookieJar]: + def get_request_cookie_jar(cls, type: str) -> RequestsCookieJar: """ 获取当前会话中指定类型的cookie数据 :param type: cookie类型 DISPATCHER_TYPE.BUILD或DISPATCHER_TYPE.DEBUG @@ -117,12 +117,12 @@ class HTTPCookiePoolManager: project_id = session.get('project_id') if project_id: if project_id not in __class__.ScheduleCookiePool: - return + cls._add_empty_to_cookie_pool() return __class__.ScheduleCookiePool[project_id] else: session_id = session_id_manager.get_session_id() if session_id not in __class__.CookiePool: - return + cls._add_empty_to_cookie_pool() return __class__.CookiePool[session_id][type] @classmethod diff --git a/ApiAutomationTest/app/cores/dictionaries.py b/ApiAutomationTest/app/cores/dictionaries.py index 833c226..2637ae8 100644 --- a/ApiAutomationTest/app/cores/dictionaries.py +++ b/ApiAutomationTest/app/cores/dictionaries.py @@ -102,6 +102,7 @@ class TOOL_TYPE: VARIABLE_DEFINITION = 'VARIABLE_DEFINITION' SCRIPT = 'SCRIPT' HTTP_REQUEST_HEADER_MANAGER = 'HTTP_REQUEST_HEADER_MANAGER' + HTTP_COOKIE_MANAGER = 'HTTP_COOKIE_MANAGER' class CONTENT_TYPE: diff --git a/ApiAutomationTest/app/cores/dispatcher.py b/ApiAutomationTest/app/cores/dispatcher.py index 95b5954..db1a55b 100644 --- a/ApiAutomationTest/app/cores/dispatcher.py +++ b/ApiAutomationTest/app/cores/dispatcher.py @@ -868,7 +868,8 @@ class SceneDispatcher(AbstractSceneDispatcher): if tool.status in [STATUS.NORMAL] and tool.tool_type in [TOOL_TYPE.TIMER, TOOL_TYPE.SCRIPT, TOOL_TYPE.VARIABLE_DEFINITION, - TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER]: + TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER, + TOOL_TYPE.HTTP_COOKIE_MANAGER]: # ReportToolData表数据字段 report_id = self.dispatcher.report.id try: @@ -890,6 +891,11 @@ class SceneDispatcher(AbstractSceneDispatcher): HTTPRequestHeaderManagerToolDispatcher(tool=tool, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=self.dispatcher_logger, dispatcher=self.dispatcher).run() + elif tool.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER: + from app.cores.tool.dispatcher import HTTPCookieManagerToolDispatcher + HTTPCookieManagerToolDispatcher(tool=tool, dispatcher_type=DISPATCHER_TYPE.BUILD, + logger=self.dispatcher_logger, + dispatcher=self.dispatcher).run() finally: # 工具增加调度子数据 dispatcher_detail_id = DispatcherDetail.add(element_type=ELEMENT_TYPE.TOOL, element_id=tool.id, diff --git a/ApiAutomationTest/app/cores/tool/dispatcher.py b/ApiAutomationTest/app/cores/tool/dispatcher.py index a8d8d35..b4344d7 100644 --- a/ApiAutomationTest/app/cores/tool/dispatcher.py +++ b/ApiAutomationTest/app/cores/tool/dispatcher.py @@ -6,6 +6,7 @@ from app.cores.tool.script import Script from app.cores.tool.timer import Timer from app.cores.tool.variable_definition import VariableDefinition from app.cores.tool.http_request_header_manager import HTTPRequestHeaderManager +from app.cores.tool.http_cookie_manager import HTTPCookieManager class ScriptToolDispatcher(AbstractToolDispatcher): @@ -127,3 +128,31 @@ class HTTPRequestHeaderManagerToolDispatcher(AbstractToolDispatcher): def run(self): super().run() + + +class HTTPCookieManagerToolDispatcher(AbstractToolDispatcher): + def __init__(self, tool, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=None, dispatcher=None): + """ + :param tool: 单个HTTPCookieManager Tool工具组件 + :type tool: Tool + :param dispatcher_type: 标识构建是通过单独组件调试(DISPATCHER_TYPE.DEBUG)还是通过模块/项目构建测试(DISPATCHER_TYPE.BUILD) + :type dispatcher_type: str + :param logger: 当dispatcher_type为DISPATCHER_TYPE.BUILD时,需要传入调度日志 + :type logger: DispatcherLogger + :param dispatcher: 当dispatcher_type为DISPATCHER_TYPE.BUILD时,需要传入调度数据 + :type dispatcher: Dispatcher + """ + super().__init__(tool=tool, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher) + + def set_up(self): + super().set_up() + + def execute(self): + super().execute() + HTTPCookieManager(tool=self.tool, dispatcher_logger=self.dispatcher_logger).exec_tool() + + def tear_down(self): + super().tear_down() + + def run(self): + super().run() diff --git a/ApiAutomationTest/app/cores/tool/http_cookie_manager.py b/ApiAutomationTest/app/cores/tool/http_cookie_manager.py new file mode 100644 index 0000000..07e949a --- /dev/null +++ b/ApiAutomationTest/app/cores/tool/http_cookie_manager.py @@ -0,0 +1,31 @@ +# coding=utf-8 +from requests.cookies import RequestsCookieJar + +from app.cores.case.http.http_cookie_pool_manager import HTTPCookiePoolManager +from app.cores.dictionaries import DISPATCHER_TYPE + + +class HTTPCookieManager: + + def __init__(self, tool, dispatcher_logger): + """ + 初始化HTTPCookieManager工具对象 + :param tool: 工具 + :type tool: Tool + :param dispatcher_logger: 日志 + :type dispatcher_logger: DispatcherLogger + """ + self.http_cookie_manager_tool = tool.specific_tool + self.dispatcher_logger = dispatcher_logger + + def exec_tool(self): + self.dispatcher_logger.logger.info('[HTTPCookie管理器][执行]') + rcj = HTTPCookiePoolManager.get_request_cookie_jar(type=DISPATCHER_TYPE.BUILD) + new_rcj = RequestsCookieJar() + for row in self.http_cookie_manager_tool.http_cookie_manager_list: + new_rcj.set(name=row.name_, + value=row.value_, + domain=row.domain_, + path=row.path_, + secure=row.secure) + HTTPCookiePoolManager.update_request_cookie_jar(old_rcj=rcj, new_rcj=new_rcj) diff --git a/ApiAutomationTest/app/models.py b/ApiAutomationTest/app/models.py index 52d2247..922e3e2 100644 --- a/ApiAutomationTest/app/models.py +++ b/ApiAutomationTest/app/models.py @@ -1004,6 +1004,8 @@ class Tool(db.Model): return VariableDefinitionTool.query.filter_by(tool_id=self.id).first() if self.tool_type == TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER: return HTTPRequestHeaderManagerTool.query.filter_by(tool_id=self.id).first() + if self.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER: + return HTTPCookieManagerTool.query.filter_by(tool_id=self.id).first() @classmethod def exist_and_status_not_delete(cls, tool_id) -> bool: @@ -1051,6 +1053,9 @@ class Tool(db.Model): elif tool_type == TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER: specific_tool = HTTPRequestHeaderManagerTool.new_tool() specific_tool.tool = tool + elif tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER: + specific_tool = HTTPCookieManagerTool.new_tool() + specific_tool.tool = tool else: raise ValueError('不支持当前tool_type类型, tool_type=%s' % tool_type) db.session.add(specific_tool) @@ -1557,6 +1562,172 @@ class HTTPRequestHeaderManagerList(db.Model): return _p(self.value) +class HTTPCookieManagerTool(db.Model): + """ + 关系说明 + tool: HTTPCookieManagerTool对应的工具对象 HTTPCookieManagerTool:Tool is 1:1 + http_cookie_manager_list: HTTPCookieManagerTool工具所包含的所有变量与值数据 HTTPCookieManagerTool:HTTPCookieManagerList is 1:N + """ + id = db.Column(db.Integer, primary_key=True) + + # relationship + tool_id = db.Column(db.Integer, db.ForeignKey('tool.id')) + tool = db.relationship('Tool') + http_cookie_manager_list = db.relationship('HTTPCookieManagerList', + back_populates='http_cookie_manager_tool', + cascade='all, delete-orphan') + + @property + def attributes(self): + return [{ + 'name': row.name, + 'value': row.value, + 'domain': row.domain, + 'path': row.path, + 'secure': row.secure, + } for row in self.http_cookie_manager_list] + + @classmethod + def new_tool(cls): + """新增默认""" + http_cookie_manager_tool = cls() + http_cookie_manager_tool.http_cookie_manager_list = [] + http_cookie_manager_tool.http_cookie_manager_list.append( + HTTPCookieManagerList(name='cookie_name', + value='cookie_value', + domain='localhost', + path='/', + secure=False) + ) + db.session.add(http_cookie_manager_tool) + db.session.commit() + return http_cookie_manager_tool + + @classmethod + def update(cls, name, description, tool_id, attributes): + """ + 更新工具数据 + :param tool_id: 工具编号 + :type tool_id: int + :param name: 名称 + :type name: str + :param description: 注释 + :type description: str + :param attributes: HTTPCookieManager数据列表 + :type attributes: List[Mapping[str, str]] + """ + tool = Tool.query.filter_by(id=tool_id).first() + if tool: + tool.name = name + tool.description = description + http_cookie_manager_tool = tool.specific_tool + http_cookie_manager_tool.http_cookie_manager_list = [] + for attr in attributes: + http_cookie_manager_tool.http_cookie_manager_list.append( + HTTPCookieManagerList(name=attr.get('name', ''), + value=attr.get('value', ''), + domain=attr.get('domain', ''), + path=attr.get('path', ''), + secure=attr.get('secure', False)) + ) + db.session.commit() + + @classmethod + def add(cls, name, description, attributes, status=STATUS.NORMAL): + """ + 新增一条工具数据 + :param name: 名称 + :type name: str + :param description: 注释 + :type description: str + :param attributes: HTTPCookieManager数据列表 + :type attributes: List[Mapping[str, str]] + :param status: 案例状态(删除 正常) + :type status: str + """ + tool = Tool( + name=name, + description=description, + status=status, + tool_type=TOOL_TYPE.HTTP_COOKIE_MANAGER, + ) + http_cookie_manager_tool = cls() + http_cookie_manager_tool.http_cookie_manager_list = [] + for attr in attributes: + http_cookie_manager_tool.http_cookie_manager_list.append( + HTTPCookieManagerList(name=attr.get('name', ''), + value=attr.get('value', ''), + domain=attr.get('domain', ''), + path=attr.get('path', ''), + secure=attr.get('secure', False)) + ) + http_cookie_manager_tool.tool = tool + db.session.add(tool) + db.session.add(http_cookie_manager_tool) + db.session.commit() + return http_cookie_manager_tool + + def copy_from_self(self): + """ + 复制一个新的工具 + :return: 新的工具 + :rtype: Tool + """ + # 先获取变量键值对数据 + copy_tool = self.add( + # Tool + name='Copy' + self.tool.name, + description=self.tool.description, + status=self.tool.status, + # HTTPCookieManagerTool + attributes=self.attributes, + ) + return copy_tool + + +class HTTPCookieManagerList(db.Model): + """ + 字段说明 + name: 名称 + value: 值 + domain: 域 + path: 路径 + secure: 安全 + 关系说明 + http_cookie_manager_tool: HTTPCookieManager数据列表对应的HTTPCookieManager工具对象 HTTPCookieManagerList:HTTPCookieManagerTool is N:1 + """ + # 需要转换为json数据格式的字段 + render_field_list = ['name', 'value', 'domain', 'path', 'secure'] + # filed + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(512), nullable=False, default='', server_default='') + value = db.Column(db.Text, nullable=False, default='', server_default='') + domain = db.Column(db.String(512), nullable=False, default='', server_default='') + path = db.Column(db.String(512), nullable=False, default='', server_default='') + secure = db.Column(db.Boolean, nullable=False, default=False, server_default='0') + + # relationship + http_cookie_manager_tool_id = db.Column(db.Integer, db.ForeignKey('http_cookie_manager_tool.id')) + http_cookie_manager_tool = db.relationship('HTTPCookieManagerTool', + back_populates='http_cookie_manager_list') + + @property + def name_(self): + return _p(self.name) + + @property + def value_(self): + return _p(self.value) + + @property + def domain_(self): + return _p(self.domain) + + @property + def path_(self): + return _p(self.path) + + class Case(db.Model): """ 字段说明 @@ -3225,6 +3396,10 @@ class ReportToolData(db.Model): back_populates='report_tool_data', uselist=False, cascade='all, delete-orphan') + report_http_cookie_manager_tool_data = db.relationship('ReportHTTPCookieManagerToolData', + back_populates='report_tool_data', + uselist=False, + cascade='all, delete-orphan') @classmethod def add(cls, tool, report_id, dispatcher_detail_id): @@ -3241,6 +3416,9 @@ class ReportToolData(db.Model): elif tool.tool_type == TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER: ReportHTTPRequestHeaderManagerToolData.add(variables=tool.specific_tool.variables, report_tool_data_id=report_tool_data.id) + elif tool.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER: + ReportHTTPCookieManagerToolData.add(attributes=tool.specific_tool.attributes, + report_tool_data_id=report_tool_data.id) return report_tool_data @@ -3368,6 +3546,59 @@ class ReportHTTPRequestHeaderManagerToolListData(db.Model): back_populates='report_http_request_header_manager_tool_list_data') +class ReportHTTPCookieManagerToolData(db.Model): + # field + id = db.Column(db.Integer, primary_key=True) + + # relationship + report_tool_data_id = db.Column(db.Integer, db.ForeignKey('report_tool_data.id')) + report_tool_data = db.relationship('ReportToolData', back_populates='report_http_cookie_manager_tool_data') + report_http_cookie_manager_tool_list_data = db.relationship('ReportHTTPCookieManagerToolListData', + back_populates='report_http_cookie_manager_tool_data', + cascade='all, delete-orphan') + + @property + def attributes(self): + return [{ + 'name': row.name, + 'value': row.value, + 'domain': row.domain, + 'path': row.path, + 'secure': row.secure, + } for row in self.report_http_cookie_manager_tool_list_data] + + @classmethod + def add(cls, attributes, report_tool_data_id): + report_http_cookie_manager_tool_data = ReportHTTPCookieManagerToolData(report_tool_data_id=report_tool_data_id) + db.session.add(report_http_cookie_manager_tool_data) + db.session.commit() # commit后report_http_cookie_manager_tool_data.id才有值,否则为None + for attr in attributes: + db.session.add(ReportHTTPCookieManagerToolListData( + name=attr.get('name', ''), + value=attr.get('value', ''), + domain=attr.get('domain', ''), + path=attr.get('path', ''), + secure=attr.get('secure', False), + report_http_cookie_manager_tool_data_id=report_http_cookie_manager_tool_data.id, + )) + db.session.commit() + + +class ReportHTTPCookieManagerToolListData(db.Model): + # field + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(512), nullable=False, default='', server_default='') + value = db.Column(db.Text, nullable=False, default='', server_default='') + domain = db.Column(db.String(512), nullable=False, default='', server_default='') + path = db.Column(db.String(512), nullable=False, default='', server_default='') + secure = db.Column(db.Boolean, nullable=False, default=False, server_default='0') + + # relationship + report_http_cookie_manager_tool_data_id = db.Column(db.Integer, db.ForeignKey('report_http_cookie_manager_tool_data.id')) + report_http_cookie_manager_tool_data = db.relationship('ReportHTTPCookieManagerToolData', + back_populates='report_http_cookie_manager_tool_list_data') + + class Scheduler(db.Model): """ 调度定时任务 diff --git a/ApiAutomationTest/app/routes/ajax/routes.py b/ApiAutomationTest/app/routes/ajax/routes.py index 4629924..cbf5d8f 100644 --- a/ApiAutomationTest/app/routes/ajax/routes.py +++ b/ApiAutomationTest/app/routes/ajax/routes.py @@ -20,7 +20,8 @@ from app.utils.util import get_form_from_request, exception_handle, get_project_ from app.models import Case, Project, Module, Scene, HTTPCase, SSHCase, SQLCase, Dispatcher, DispatcherDetail, Report, \ SubElementInLogicController, LogicController, IfController, WhileController, LoopController, SimpleController, \ Scheduler, DingTalkRobotSetting, DingTalkRobotSettingAssociationProject, DebugCase, Tool, TimerTool, ScriptTool, \ - VariableDefinitionTool, EmailReceiverSetting, EmailReceiverSettingAssociationProject, HTTPRequestHeaderManagerTool + VariableDefinitionTool, EmailReceiverSetting, EmailReceiverSettingAssociationProject, HTTPRequestHeaderManagerTool,\ + HTTPCookieManagerTool from app.template_global import render_to_json from app.extensions import dispatcher_scheduler from app.template_global import sort_by_order_in_project, sort_by_order_in_module, sort_by_order_in_logic_controller @@ -799,6 +800,39 @@ def save_http_request_header_manager_tool(): }) +@bp.route('/tool/http_cookie_manager/save', methods=['POST']) +@login_required +def save_http_cookie_manager_tool(): + # 参数校验 + exist, form_tool_id = get_form_from_request(request, 'tool_id') + if not exist: return form_tool_id + exist, form_tool_name = get_form_from_request(request, 'tool_name') + if not exist: return form_tool_name + exist, form_tool_description = get_form_from_request(request, 'tool_description') + if not exist: return form_tool_description + exist, form_attrs = get_form_from_request(request, 'attrs') + if not exist: return form_attrs + try: + attributes = json.loads(form_attrs) + HTTPCookieManagerTool.update( + tool_id=form_tool_id, + name=form_tool_name, + description=form_tool_description, + attributes=attributes, + ) + except Exception as e: + exception_handle(current_app, e) + return jsonify({ + 'error_no': -1, + 'error_msg': '错误信息 [' + repr(e) + ']', + }) + else: + return jsonify({ + 'error_no': 0, + 'error_msg': '', + }) + + @bp.route('/tool/script/run', methods=['POST']) @login_required def run_script_tool(): @@ -2290,6 +2324,7 @@ def get_report_detail_tool(): }) report_tool_data = dispatcher_detail.specific_element_report_data variables = [] + attributes = [] if report_tool_data.tool_type == TOOL_TYPE.TIMER: html_text = render_template('report/_report_detail_timer_tool.html', dispatcher_detail=dispatcher_detail, @@ -2308,6 +2343,11 @@ def get_report_detail_tool(): dispatcher_detail=dispatcher_detail, report_tool_data=report_tool_data) variables = report_tool_data.report_http_request_header_manager_tool_data.variables + elif report_tool_data.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER: + html_text = render_template('report/_report_detail_http_cookie_manager_tool.html', + dispatcher_detail=dispatcher_detail, + report_tool_data=report_tool_data) + attributes = report_tool_data.report_http_cookie_manager_tool_data.attributes else: html_text = '' except Exception as e: @@ -2323,6 +2363,7 @@ def get_report_detail_tool(): 'html_text': html_text, 'tool_type': report_tool_data.tool_type, 'variables': variables, + 'attributes': attributes, }) @@ -2548,6 +2589,7 @@ def tool(): 'error_msg': '错误信息 [未找工具数据tool_id=%s]' % form_tool_id, }) data_variables = [] + data_attributes = [] if tool.tool_type == TOOL_TYPE.TIMER: html_text = render_template('tool/timer.html', tool=tool) elif tool.tool_type == TOOL_TYPE.SCRIPT: @@ -2558,6 +2600,9 @@ def tool(): elif tool.tool_type == TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER: html_text = render_template('tool/http_request_header_manager.html', tool=tool) data_variables = json.loads(render_to_json(tool.specific_tool.http_request_header_manager_list)) + elif tool.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER: + html_text = render_template('tool/http_cookie_manager.html', tool=tool) + data_attributes = json.loads(render_to_json(tool.specific_tool.http_cookie_manager_list)) else: return jsonify({ 'error_no': -1, @@ -2577,6 +2622,7 @@ def tool(): 'tool_type': tool.tool_type, 'html_text': html_text, 'data_variables': data_variables, + 'data_attributes': data_attributes, }) diff --git a/ApiAutomationTest/app/static/css/base.css b/ApiAutomationTest/app/static/css/base.css index 5be4039..2db1e6d 100644 --- a/ApiAutomationTest/app/static/css/base.css +++ b/ApiAutomationTest/app/static/css/base.css @@ -199,6 +199,9 @@ body { .icon-tool-http-request-header-manager{ background-image: url(/static/icon/http-request-header.svg); } +.icon-tool-http-cookie-manager{ + background-image: url(/static/icon/cookie.svg); +} /*div边框样式*/ .border-left-primary { diff --git a/ApiAutomationTest/app/static/icon/cookie.svg b/ApiAutomationTest/app/static/icon/cookie.svg new file mode 100644 index 0000000..9aa506f --- /dev/null +++ b/ApiAutomationTest/app/static/icon/cookie.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/ApiAutomationTest/app/static/js/report/report_detail.js b/ApiAutomationTest/app/static/js/report/report_detail.js index 37fb40b..51fabfb 100644 --- a/ApiAutomationTest/app/static/js/report/report_detail.js +++ b/ApiAutomationTest/app/static/js/report/report_detail.js @@ -236,6 +236,9 @@ function renderToolReportDetail(node){ }else if(data.tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){ // 渲染HTTPRequestHeaderManagerTool工具组件页面 renderHTTPRequestHeaderManagerToolPage(node.data.dispatcher_detail_id, data.variables); + }else if(data.tool_type === 'HTTP_COOKIE_MANAGER'){ + // 渲染HTTPCookieManagerTool工具组件页面 + renderHTTPCookieManagerToolPage(node.data.dispatcher_detail_id, data.attributes); } resolve(['成功了', 'success']); // 也可以传递其他类型参数 }else{ @@ -721,6 +724,92 @@ function renderHTTPRequestHeaderManagerToolPage(dispatcher_detail_id, data_varia table_http_request_header_manager = $container.handsontable(option_table_http_request_header_manager).handsontable('getInstance'); } } +// 渲染HTTPCookieManagerTool工具组件页面 +function renderHTTPCookieManagerToolPage(dispatcher_detail_id, data_attributes) { + // HTTPCookieManager表格对象 + let table_http_cookie_manager = null; + + // 渲染HTTPCookieManager表格 + renderHTTPCookieManagerTable(); + + // 渲染HTTPCookieManager表格 + function renderHTTPCookieManagerTable() { + const option_table_http_request_header_manager = { + data: data_attributes, + rowHeaders: true, + // colHeaders: true, + licenseKey: 'non-commercial-and-evaluation', + // 表格宽度 + // width: '95vw', // 不指定宽度使其自适应容器 + // 拉伸方式 + stretchH: 'all', + // tab键自动换行切换 + autoWrapRow: true, + height: '55vh', + // 最大行数 + maxRows: 999, + // 允许手工移动行或列 + manualRowResize: true, + manualColumnResize: true, + // 列名 + colHeaders: [ + '名称', + '值', + '域', + '路径', + '安全', + ], + // 为列设置默认值 + dataSchema: { + name: '', + value: '', + url_encode: false, + content_type: 'text/plain', + include_equals: true, + }, + // 设置列数据类型 + columns: [ + { + data: 'name', + readOnly: true, + }, + { + data: 'value', + readOnly: true, + }, + { + data: 'domain', + readOnly: true, + }, + { + data: 'path', + readOnly: true, + }, + { + data: 'secure', + type: 'checkbox', + readOnly: true, + }, + ], + // 列宽比例 + colWidths: [2, 5, 5, 3, 1], + manualRowMove: true, + manualColumnMove: false, + // 右键菜单 + // contextMenu: ['row_above', 'row_below', '---------', 'remove_row', '---------', 'undo', 'redo', '---------', 'alignment', '---------', 'copy', 'cut'], + // 列是否支持过滤 + filters: false, + // 下拉菜单 + // dropdownMenu: ['make_read_only', '---------', 'alignment'], + // 语言 + language: 'zh-CN', + // 是否允许无效数据 默认 true + allowInvalid: false, + }; + let $container = $(`#table-http-cookie-manager-${dispatcher_detail_id}`); + table_http_cookie_manager = $container.handsontable(option_table_http_request_header_manager).handsontable('getInstance'); + } +} // 渲染报告图表 function renderEcharts() { @@ -872,6 +961,8 @@ function renderReportTree() { $(`#table-variable-definition-${dispatcher_detail_id}`).handsontable('getInstance').render(); }else if(element_type === 'TOOL' && node.data.tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){ $(`#table-http-request-header-manager-${dispatcher_detail_id}`).handsontable('getInstance').render(); + }else if(element_type === 'TOOL' && node.data.tool_type === 'HTTP_COOKIE_MANAGER'){ + $(`#table-http-cookie-manager-${dispatcher_detail_id}`).handsontable('getInstance').render(); } }, 1000, @@ -955,6 +1046,8 @@ function renderReportTree() { return 'icon-tool-variable-definition'; }else if(tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){ return 'icon-tool-http-request-header-manager'; + }else if(tool_type === 'HTTP_COOKIE_MANAGER'){ + return 'icon-tool-http-cookie-manager'; } }else if(element_type === undefined) { return true; diff --git a/ApiAutomationTest/app/static/js/scene/scene.js b/ApiAutomationTest/app/static/js/scene/scene.js index 3a47c83..5e4ec25 100644 --- a/ApiAutomationTest/app/static/js/scene/scene.js +++ b/ApiAutomationTest/app/static/js/scene/scene.js @@ -478,6 +478,8 @@ function renderElementCopyTree() { return 'icon-tool-variable-definition'; }else if(tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){ return 'icon-tool-http-request-header-manager'; + }else if(tool_type === 'HTTP_COOKIE_MANAGER'){ + return 'icon-tool-http-cookie-manager'; } }else if(element_type === undefined) { return true; @@ -1516,6 +1518,8 @@ function showTool(tool_id, tool_type) { $(`#table-variable-definition-${tool_id}`).handsontable('getInstance').render(); }else if(tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){ $(`#table-http-request-header-manager-${tool_id}`).handsontable('getInstance').render(); + }else if(tool_type === 'HTTP_COOKIE_MANAGER'){ + $(`#table-http-cookie-manager-${tool_id}`).handsontable('getInstance').render(); } }, 1000, @@ -1899,6 +1903,10 @@ function addToolElement(tool_id) { let element = getHTTPRequestHeaderManagerToolElement(data.tool_id); element.init(data.data_variables); element_tool_dict[data.tool_id] = element; + }else if(data.tool_type === 'HTTP_COOKIE_MANAGER') { + let element = getHTTPCookieManagerToolElement(data.tool_id); + element.init(data.data_attributes); + element_tool_dict[data.tool_id] = element; } resolve(['成功了', 'success']); // 也可以传递其他类型参数 }else{ diff --git a/ApiAutomationTest/app/static/js/tool/http_cookie_manager.js b/ApiAutomationTest/app/static/js/tool/http_cookie_manager.js new file mode 100644 index 0000000..84753ca --- /dev/null +++ b/ApiAutomationTest/app/static/js/tool/http_cookie_manager.js @@ -0,0 +1,159 @@ +function getHTTPCookieManagerToolElement(tool_id) { + let element = new Object; + element.dom = new Object; + element.obj = new Object; + + // 案例页面元素 + element.dom.$input_tool_name = $(`#input-tool-name-${tool_id}`); + element.dom.$input_tool_description = $(`#input-tool-description-${tool_id}`); + element.dom.$btn_tool_save = $(`#btn-tool-save-${tool_id}`); + element.dom.$div_navigation_tool_name = $(`.tool-name[data-tool-id=${tool_id}]`); + + // 对象 + element.obj.table_http_cookie_manager = null; // 变量定义表格 + + // 初始化 + element.init = function(data_variables) { + // 事件绑定 + eventBinding(); + // 渲染HTTPCookie管理器表格 + renderHTTPCookieManagerTable(data_variables); + }; + + // 事件绑定 + function eventBinding() { + element.dom.$input_tool_name.on('change keyup', handleKeyUpAndChange); + element.dom.$btn_tool_save.on('click', saveTool); + + function handleKeyUpAndChange(){ + let tool_name = element.dom.$input_tool_name.val(); + element.dom.$div_navigation_tool_name.children().text(tool_name); + } + } + + // 渲染HTTPCookie管理器表格 + function renderHTTPCookieManagerTable(data_attributes) { + const option_table_http_cookie_manager = { + data: data_attributes, + rowHeaders: true, + // colHeaders: true, + licenseKey: 'non-commercial-and-evaluation', + // 表格宽度 + // width: '95vw', // 不指定宽度使其自适应容器 + // 拉伸方式 + stretchH: 'all', + // tab键自动换行切换 + autoWrapRow: true, + height: '65vh', + // 最大行数 + maxRows: 999, + // 允许手工移动行或列 + manualRowResize: true, + manualColumnResize: true, + // 列名 + colHeaders: [ + '名称', + '值', + '域', + '路径', + '安全', + ], + // 为列设置默认值 + dataSchema: { + name: '', + value: '', + url_encode: false, + content_type: 'text/plain', + include_equals: true, + }, + // 设置列数据类型 + columns: [ + { + data: 'name' + }, + { + data: 'value', + }, + { + data: 'domain', + }, + { + data: 'path', + }, + { + data: 'secure', + type: 'checkbox', + }, + ], + // 列宽比例 + colWidths: [2, 5, 5, 3, 1], + manualRowMove: true, + manualColumnMove: false, + // 右键菜单 + contextMenu: ['row_above', 'row_below', '---------', 'remove_row', '---------', 'undo', 'redo', '---------', 'alignment', '---------', 'copy', 'cut'], + // 列是否支持过滤 + filters: false, + // 下拉菜单 + dropdownMenu: ['make_read_only', '---------', 'alignment'], + // 语言 + language: 'zh-CN', + // 是否允许无效数据 默认 true + allowInvalid: false, + }; + let $container = $(`#table-http-cookie-manager-${tool_id}`); + element.obj.table_http_cookie_manager = $container.handsontable(option_table_http_cookie_manager).handsontable('getInstance'); + } + + function saveTool() { + let tool_name = element.dom.$input_tool_name.val(); + let tool_description = element.dom.$input_tool_description.val(); + $.ajax({ + type: 'POST', + url: '/ajax/tool/http_cookie_manager/save', + data: { + tool_id: tool_id, + tool_name: tool_name, + tool_description: tool_description, + attrs: JSON.stringify(element.obj.table_http_cookie_manager.getSourceData()), + }, + success: function (data, status, xhr) { + if (data.error_no === 0){ + message('HTTPCookie保存成功', 'success'); + }else{ + message("HTTPCookie保存失败: " + data.error_msg, "error"); + } + } + }); + } + + // 关键词查找 + element.mark = function (text) { + // 匹配到则返回true + let pat = new RegExp(text); + let value = ''; + let markFlag = false; + // 名称 + value = element.dom.$input_tool_name.val(); + if (pat.test(value)) return true; + // 注释 + value = element.dom.$input_tool_description.val(); + if (pat.test(value)) return true; + // 期望表格 + markFlag = false; + value = element.obj.table_http_cookie_manager.getSourceData(); + $.each(value, function (index, row) { + $.each(row, function (column, data) { + if (pat.test(data)){ + markFlag = true; + return false; + } + }); + }); + if (markFlag) return true; + + // 未匹配到返回false + return false; + }; + + return element; +} \ No newline at end of file diff --git a/ApiAutomationTest/app/templates/report/_report_detail_http_cookie_manager_tool.html b/ApiAutomationTest/app/templates/report/_report_detail_http_cookie_manager_tool.html new file mode 100644 index 0000000..4d4c08f --- /dev/null +++ b/ApiAutomationTest/app/templates/report/_report_detail_http_cookie_manager_tool.html @@ -0,0 +1,10 @@ +
\ No newline at end of file diff --git a/ApiAutomationTest/app/templates/scene/_single_scene.html b/ApiAutomationTest/app/templates/scene/_single_scene.html index acac7e5..c512fba 100644 --- a/ApiAutomationTest/app/templates/scene/_single_scene.html +++ b/ApiAutomationTest/app/templates/scene/_single_scene.html @@ -100,6 +100,15 @@定义HTTPCookie.
+